Re: [alsa-devel] [PATCH 15/27] ALSA: hda - Use timecounter_initialize interface
On 1/5/2018 9:13 PM, Pierre-Louis Bossart wrote: On 1/5/18 4:06 AM, Sagar Arun Kamble wrote: On 1/3/2018 1:23 AM, Pierre-Louis Bossart wrote: On 1/2/18 12:21 PM, Richard Cochran wrote: On Tue, Jan 02, 2018 at 11:15:45AM -0600, Pierre-Louis Bossart wrote: I wrote the code for HDaudio and I remember wasting time trying to figure out the gory details of the cycle counter stuff when all I wanted was a conversion from a 24MHz counter to ns values using a 125/3 operation in the right order - as explained in the comments Would using clocks_calc_mult_shift() work for you? In theory yes, but I'd need to re-check what the results would be. I remember applying the 1/3 factor separately to avoid wrap-around after 4 hours [1], but I can't remember the details on the analysis. I can't figure out what the 'maxsec' argument should be either. I am not sure if I understood the wrap-around correctly. Is AZX_REG_WALL_CLK 64bit or 32bit and in the comments which 20 bits are being referred. it's a 32-bit counter. off the top of my head, the idea was that the integer arithmetic should not degrade the precision (42ns) and that means you need to be careful with the fractional part, especially if the errors with the fractional part accumulate over time (I think this was the case when I looked several years ago). That's the main reason why I did the division by 3 last, after the read, so that the precision is not impacted by the interval between two reads. timecounter interface ensures to add the fractional ns time so it has good precision. In the table below 3600 indicates interval of 1min between two counter reads and 14400 indicates that interval of 4 minutes. Shift factor controls the ns precision we want. Considering duration of 195 years of interval between counter reads at 24mhz we get mult=83 and shift=1 which will give cycle duration = 41.5. What is the maximum duration of interval over which this read can be done in audio driver. You also need to be careful with the multiplication factor otherwise you will exceed the 64-bit resolution. For example with the 14400 factor, you cannot handle a counter larger than 2^64/14400, which gives you 14826 hours or 1.69 years. It's one of those 'nobody will ever need more than 640KB' value. The 125 factor gives you 195 years without saturating. Keeping maxsec at lower value will ensure good precision but the mult factor derived then might lead to overflow if the interval of counter read is big. Keeping maxsec high will reduce the mult factor and will marginally impact the precision (of the order of 6 decimal places of fraction nano second). For 24mhz clock I am getting following scale factors at different maxsec values. I think these are as good as 125/3 125/3 gives scale factor of 41.67 maxsec, mult, shift, scale factor (mult/(2^shift)) 0, 2796202667, 26, 41.6667163372039794921875 3600, 87381333, 21, 41.66507720947265625 14400, 21845333, 19, 41.660308837890625 I see sound driver uses only timecounter_read so conversions should be fine. If there are usages of timecounter_cyc2time then we will have to take care of updating the timecounter often as timecounter API internally counts time backwards if counter is spaced more than 1/2 the range. Thanks Sagar [1] http://elixir.free-electrons.com/linux/latest/source/sound/hda/hdac_stream.c#L486
Re: [alsa-devel] [PATCH 15/27] ALSA: hda - Use timecounter_initialize interface
On 1/5/2018 9:13 PM, Pierre-Louis Bossart wrote: On 1/5/18 4:06 AM, Sagar Arun Kamble wrote: On 1/3/2018 1:23 AM, Pierre-Louis Bossart wrote: On 1/2/18 12:21 PM, Richard Cochran wrote: On Tue, Jan 02, 2018 at 11:15:45AM -0600, Pierre-Louis Bossart wrote: I wrote the code for HDaudio and I remember wasting time trying to figure out the gory details of the cycle counter stuff when all I wanted was a conversion from a 24MHz counter to ns values using a 125/3 operation in the right order - as explained in the comments Would using clocks_calc_mult_shift() work for you? In theory yes, but I'd need to re-check what the results would be. I remember applying the 1/3 factor separately to avoid wrap-around after 4 hours [1], but I can't remember the details on the analysis. I can't figure out what the 'maxsec' argument should be either. I am not sure if I understood the wrap-around correctly. Is AZX_REG_WALL_CLK 64bit or 32bit and in the comments which 20 bits are being referred. it's a 32-bit counter. off the top of my head, the idea was that the integer arithmetic should not degrade the precision (42ns) and that means you need to be careful with the fractional part, especially if the errors with the fractional part accumulate over time (I think this was the case when I looked several years ago). That's the main reason why I did the division by 3 last, after the read, so that the precision is not impacted by the interval between two reads. timecounter interface ensures to add the fractional ns time so it has good precision. In the table below 3600 indicates interval of 1min between two counter reads and 14400 indicates that interval of 4 minutes. Shift factor controls the ns precision we want. Considering duration of 195 years of interval between counter reads at 24mhz we get mult=83 and shift=1 which will give cycle duration = 41.5. What is the maximum duration of interval over which this read can be done in audio driver. You also need to be careful with the multiplication factor otherwise you will exceed the 64-bit resolution. For example with the 14400 factor, you cannot handle a counter larger than 2^64/14400, which gives you 14826 hours or 1.69 years. It's one of those 'nobody will ever need more than 640KB' value. The 125 factor gives you 195 years without saturating. Keeping maxsec at lower value will ensure good precision but the mult factor derived then might lead to overflow if the interval of counter read is big. Keeping maxsec high will reduce the mult factor and will marginally impact the precision (of the order of 6 decimal places of fraction nano second). For 24mhz clock I am getting following scale factors at different maxsec values. I think these are as good as 125/3 125/3 gives scale factor of 41.67 maxsec, mult, shift, scale factor (mult/(2^shift)) 0, 2796202667, 26, 41.6667163372039794921875 3600, 87381333, 21, 41.66507720947265625 14400, 21845333, 19, 41.660308837890625 I see sound driver uses only timecounter_read so conversions should be fine. If there are usages of timecounter_cyc2time then we will have to take care of updating the timecounter often as timecounter API internally counts time backwards if counter is spaced more than 1/2 the range. Thanks Sagar [1] http://elixir.free-electrons.com/linux/latest/source/sound/hda/hdac_stream.c#L486
Re: [Intel-wired-lan] [PATCH 01/27] timecounter: Make cyclecounter struct part of timecounter struct
Thanks Aaron. Regards, Sagar On 1/9/2018 3:50 AM, Brown, Aaron F wrote: From: Intel-wired-lan [mailto:intel-wired-lan-boun...@osuosl.org] On Behalf Of Sagar Arun Kamble Sent: Thursday, December 14, 2017 11:38 PM To: linux-kernel@vger.kernel.org Cc: alsa-de...@alsa-project.org; linux-r...@vger.kernel.org; net...@vger.kernel.org; Richard Cochran <richardcoch...@gmail.com>; Stephen Boyd <sb...@codeaurora.org>; Chris Wilson <chris@chris- wilson.co.uk>; John Stultz <john.stu...@linaro.org>; intel-wired- l...@lists.osuosl.org; Thomas Gleixner <t...@linutronix.de>; Kamble, Sagar A <sagar.a.kam...@intel.com>; kvm...@lists.cs.columbia.edu; linux-arm- ker...@lists.infradead.org Subject: [Intel-wired-lan] [PATCH 01/27] timecounter: Make cyclecounter struct part of timecounter struct There is no real need for the users of timecounters to define cyclecounter and timecounter variables separately. Since timecounter will always be based on cyclecounter, have cyclecounter struct as member of timecounter struct. v2: Rebase. Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk> Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Chris Wilson <ch...@chris-wilson.co.uk> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: John Stultz <john.stu...@linaro.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Stephen Boyd <sb...@codeaurora.org> Cc: linux-kernel@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Cc: net...@vger.kernel.org Cc: intel-wired-...@lists.osuosl.org Cc: linux-r...@vger.kernel.org Cc: alsa-de...@alsa-project.org Cc: kvm...@lists.cs.columbia.edu Acked-by: Jeff Kirsher <jeffrey.t.kirs...@intel.com> (Intel drivers) --- arch/microblaze/kernel/timer.c | 20 ++-- drivers/clocksource/arm_arch_timer.c | 19 ++-- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 9 +++--- drivers/net/ethernet/amd/xgbe/xgbe.h | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x.h| 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 20 ++-- drivers/net/ethernet/freescale/fec.h | 1 - drivers/net/ethernet/freescale/fec_ptp.c | 30 +- drivers/net/ethernet/intel/e1000e/e1000.h | 1 - drivers/net/ethernet/intel/e1000e/netdev.c | 27 drivers/net/ethernet/intel/e1000e/ptp.c| 2 +- drivers/net/ethernet/intel/igb/igb.h | 1 - drivers/net/ethernet/intel/igb/igb_ptp.c | 25 --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 - drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 17 +- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 28 - drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 34 ++-- drivers/net/ethernet/qlogic/qede/qede_ptp.c| 20 ++-- drivers/net/ethernet/ti/cpts.c | 36 -- drivers/net/ethernet/ti/cpts.h | 1 - include/linux/mlx5/driver.h| 1 - include/linux/timecounter.h| 4 +-- include/sound/hdaudio.h| 1 - kernel/time/timecounter.c | 28 - sound/hda/hdac_stream.c| 7 +++-- virt/kvm/arm/arch_timer.c | 6 ++-- 28 files changed, 163 insertions(+), 182 deletions(-) For Intel e1000e and igb drivers: Tested-by: Aaron Brown <aaron.f.br...@intel.com>
Re: [Intel-wired-lan] [PATCH 01/27] timecounter: Make cyclecounter struct part of timecounter struct
Thanks Aaron. Regards, Sagar On 1/9/2018 3:50 AM, Brown, Aaron F wrote: From: Intel-wired-lan [mailto:intel-wired-lan-boun...@osuosl.org] On Behalf Of Sagar Arun Kamble Sent: Thursday, December 14, 2017 11:38 PM To: linux-kernel@vger.kernel.org Cc: alsa-de...@alsa-project.org; linux-r...@vger.kernel.org; net...@vger.kernel.org; Richard Cochran ; Stephen Boyd ; Chris Wilson ; John Stultz ; intel-wired- l...@lists.osuosl.org; Thomas Gleixner ; Kamble, Sagar A ; kvm...@lists.cs.columbia.edu; linux-arm- ker...@lists.infradead.org Subject: [Intel-wired-lan] [PATCH 01/27] timecounter: Make cyclecounter struct part of timecounter struct There is no real need for the users of timecounters to define cyclecounter and timecounter variables separately. Since timecounter will always be based on cyclecounter, have cyclecounter struct as member of timecounter struct. v2: Rebase. Suggested-by: Chris Wilson Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Richard Cochran Cc: John Stultz Cc: Thomas Gleixner Cc: Stephen Boyd Cc: linux-kernel@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Cc: net...@vger.kernel.org Cc: intel-wired-...@lists.osuosl.org Cc: linux-r...@vger.kernel.org Cc: alsa-de...@alsa-project.org Cc: kvm...@lists.cs.columbia.edu Acked-by: Jeff Kirsher (Intel drivers) --- arch/microblaze/kernel/timer.c | 20 ++-- drivers/clocksource/arm_arch_timer.c | 19 ++-- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 9 +++--- drivers/net/ethernet/amd/xgbe/xgbe.h | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x.h| 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 20 ++-- drivers/net/ethernet/freescale/fec.h | 1 - drivers/net/ethernet/freescale/fec_ptp.c | 30 +- drivers/net/ethernet/intel/e1000e/e1000.h | 1 - drivers/net/ethernet/intel/e1000e/netdev.c | 27 drivers/net/ethernet/intel/e1000e/ptp.c| 2 +- drivers/net/ethernet/intel/igb/igb.h | 1 - drivers/net/ethernet/intel/igb/igb_ptp.c | 25 --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 - drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 17 +- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 28 - drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 34 ++-- drivers/net/ethernet/qlogic/qede/qede_ptp.c| 20 ++-- drivers/net/ethernet/ti/cpts.c | 36 -- drivers/net/ethernet/ti/cpts.h | 1 - include/linux/mlx5/driver.h| 1 - include/linux/timecounter.h| 4 +-- include/sound/hdaudio.h| 1 - kernel/time/timecounter.c | 28 - sound/hda/hdac_stream.c| 7 +++-- virt/kvm/arm/arch_timer.c | 6 ++-- 28 files changed, 163 insertions(+), 182 deletions(-) For Intel e1000e and igb drivers: Tested-by: Aaron Brown
Re: [alsa-devel] [PATCH 15/27] ALSA: hda - Use timecounter_initialize interface
On 1/3/2018 1:23 AM, Pierre-Louis Bossart wrote: On 1/2/18 12:21 PM, Richard Cochran wrote: On Tue, Jan 02, 2018 at 11:15:45AM -0600, Pierre-Louis Bossart wrote: I wrote the code for HDaudio and I remember wasting time trying to figure out the gory details of the cycle counter stuff when all I wanted was a conversion from a 24MHz counter to ns values using a 125/3 operation in the right order - as explained in the comments Would using clocks_calc_mult_shift() work for you? In theory yes, but I'd need to re-check what the results would be. I remember applying the 1/3 factor separately to avoid wrap-around after 4 hours [1], but I can't remember the details on the analysis. I can't figure out what the 'maxsec' argument should be either. I am not sure if I understood the wrap-around correctly. Is AZX_REG_WALL_CLK 64bit or 32bit and in the comments which 20 bits are being referred. Keeping maxsec at lower value will ensure good precision but the mult factor derived then might lead to overflow if the interval of counter read is big. Keeping maxsec high will reduce the mult factor and will marginally impact the precision (of the order of 6 decimal places of fraction nano second). For 24mhz clock I am getting following scale factors at different maxsec values. I think these are as good as 125/3 125/3 gives scale factor of 41.67 maxsec, mult, shift, scale factor (mult/(2^shift)) 0, 2796202667, 26, 41.6667163372039794921875 3600, 87381333, 21, 41.66507720947265625 14400, 21845333, 19, 41.660308837890625 I see sound driver uses only timecounter_read so conversions should be fine. If there are usages of timecounter_cyc2time then we will have to take care of updating the timecounter often as timecounter API internally counts time backwards if counter is spaced more than 1/2 the range. Thanks Sagar [1] http://elixir.free-electrons.com/linux/latest/source/sound/hda/hdac_stream.c#L486
Re: [alsa-devel] [PATCH 15/27] ALSA: hda - Use timecounter_initialize interface
On 1/3/2018 1:23 AM, Pierre-Louis Bossart wrote: On 1/2/18 12:21 PM, Richard Cochran wrote: On Tue, Jan 02, 2018 at 11:15:45AM -0600, Pierre-Louis Bossart wrote: I wrote the code for HDaudio and I remember wasting time trying to figure out the gory details of the cycle counter stuff when all I wanted was a conversion from a 24MHz counter to ns values using a 125/3 operation in the right order - as explained in the comments Would using clocks_calc_mult_shift() work for you? In theory yes, but I'd need to re-check what the results would be. I remember applying the 1/3 factor separately to avoid wrap-around after 4 hours [1], but I can't remember the details on the analysis. I can't figure out what the 'maxsec' argument should be either. I am not sure if I understood the wrap-around correctly. Is AZX_REG_WALL_CLK 64bit or 32bit and in the comments which 20 bits are being referred. Keeping maxsec at lower value will ensure good precision but the mult factor derived then might lead to overflow if the interval of counter read is big. Keeping maxsec high will reduce the mult factor and will marginally impact the precision (of the order of 6 decimal places of fraction nano second). For 24mhz clock I am getting following scale factors at different maxsec values. I think these are as good as 125/3 125/3 gives scale factor of 41.67 maxsec, mult, shift, scale factor (mult/(2^shift)) 0, 2796202667, 26, 41.6667163372039794921875 3600, 87381333, 21, 41.66507720947265625 14400, 21845333, 19, 41.660308837890625 I see sound driver uses only timecounter_read so conversions should be fine. If there are usages of timecounter_cyc2time then we will have to take care of updating the timecounter often as timecounter API internally counts time backwards if counter is spaced more than 1/2 the range. Thanks Sagar [1] http://elixir.free-electrons.com/linux/latest/source/sound/hda/hdac_stream.c#L486
Re: [alsa-devel] [PATCH 15/27] ALSA: hda - Use timecounter_initialize interface
On 12/28/2017 10:19 PM, Richard Cochran wrote: On Tue, Dec 26, 2017 at 01:07:35PM +0530, Sagar Arun Kamble wrote: Or can we provide simpler versions for covering some defaults? At least reducing the number of arguments would make things easier. Thought about specifying 1. cyclecounter read func 2. frequency 3. width of counter as parameters here which can get rid of mult, shift params. But this is not easy as most of the drivers do not specify cyclecounter frequency and instead hard-code the mult/shift factors. You are talking about using clocks_calc_mult_shift() here, right? (See the usage example in drivers/net/ethernet/ti/cpts.c). Yes This is a good idea, and it is worth getting the driver authors' input to figure out the correct parameters. I bet we can use that almost everywhere. If there are any drivers that cannot be converted, then we can leave some sort of low level legacy initialization method. Agree Thanks, Richard
Re: [alsa-devel] [PATCH 15/27] ALSA: hda - Use timecounter_initialize interface
On 12/28/2017 10:19 PM, Richard Cochran wrote: On Tue, Dec 26, 2017 at 01:07:35PM +0530, Sagar Arun Kamble wrote: Or can we provide simpler versions for covering some defaults? At least reducing the number of arguments would make things easier. Thought about specifying 1. cyclecounter read func 2. frequency 3. width of counter as parameters here which can get rid of mult, shift params. But this is not easy as most of the drivers do not specify cyclecounter frequency and instead hard-code the mult/shift factors. You are talking about using clocks_calc_mult_shift() here, right? (See the usage example in drivers/net/ethernet/ti/cpts.c). Yes This is a good idea, and it is worth getting the driver authors' input to figure out the correct parameters. I bet we can use that almost everywhere. If there are any drivers that cannot be converted, then we can leave some sort of low level legacy initialization method. Agree Thanks, Richard
Re: [alsa-devel] [PATCH 15/27] ALSA: hda - Use timecounter_initialize interface
On 12/15/2017 10:40 PM, Takashi Iwai wrote: On Fri, 15 Dec 2017 17:51:25 +0100, Richard Cochran wrote: On Fri, Dec 15, 2017 at 12:10:47PM +0100, Takashi Iwai wrote: - struct cyclecounter *cc = _dev->tc.cc; - cc->read = azx_cc_read; - cc->mask = CLOCKSOURCE_MASK(32); - cc->mult = 125; /* saturation after 195 years */ - cc->shift = 0; I want to get away from this mess of open coded structure initialization and use a proper functional interface instead. I agree that a proper functional interface would be better, too. But not a form like foo(501, 21, 10, 499, 5678). In C syntax, you may more easily pass a wrong value than open codes. nsec = 0; /* audio time is elapsed time since trigger */ - timecounter_init(tc, nsec); + timecounter_initialize(tc, + azx_cc_read, + CLOCKSOURCE_MASK(32), + 125, /* saturation after 195 years */ + 0, + nsec); Hmm, a function with so many arguments is difficult to remember and is often error-prone. By this transition, it becomes harder to read through. Please suggest a better way. I have no good idea ATM, sorry. Or can we provide simpler versions for covering some defaults? At least reducing the number of arguments would make things easier. Thought about specifying 1. cyclecounter read func 2. frequency 3. width of counter as parameters here which can get rid of mult, shift params. But this is not easy as most of the drivers do not specify cyclecounter frequency and instead hard-code the mult/shift factors. How about passing initialized cyclecounter struct? Takashi
Re: [alsa-devel] [PATCH 15/27] ALSA: hda - Use timecounter_initialize interface
On 12/15/2017 10:40 PM, Takashi Iwai wrote: On Fri, 15 Dec 2017 17:51:25 +0100, Richard Cochran wrote: On Fri, Dec 15, 2017 at 12:10:47PM +0100, Takashi Iwai wrote: - struct cyclecounter *cc = _dev->tc.cc; - cc->read = azx_cc_read; - cc->mask = CLOCKSOURCE_MASK(32); - cc->mult = 125; /* saturation after 195 years */ - cc->shift = 0; I want to get away from this mess of open coded structure initialization and use a proper functional interface instead. I agree that a proper functional interface would be better, too. But not a form like foo(501, 21, 10, 499, 5678). In C syntax, you may more easily pass a wrong value than open codes. nsec = 0; /* audio time is elapsed time since trigger */ - timecounter_init(tc, nsec); + timecounter_initialize(tc, + azx_cc_read, + CLOCKSOURCE_MASK(32), + 125, /* saturation after 195 years */ + 0, + nsec); Hmm, a function with so many arguments is difficult to remember and is often error-prone. By this transition, it becomes harder to read through. Please suggest a better way. I have no good idea ATM, sorry. Or can we provide simpler versions for covering some defaults? At least reducing the number of arguments would make things easier. Thought about specifying 1. cyclecounter read func 2. frequency 3. width of counter as parameters here which can get rid of mult, shift params. But this is not easy as most of the drivers do not specify cyclecounter frequency and instead hard-code the mult/shift factors. How about passing initialized cyclecounter struct? Takashi
[PATCH 04/27] clocksource/arm_arch_timer: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update arch_timer_kvm_info timecounter init with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Mark Rutland <mark.rutl...@arm.com> Cc: Marc Zyngier <marc.zyng...@arm.com> Cc: Daniel Lezcano <daniel.lezc...@linaro.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: linux-arm-ker...@lists.infradead.org Cc: linux-kernel@vger.kernel.org --- drivers/clocksource/arm_arch_timer.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 31543e5..d96393f 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -910,10 +910,7 @@ static u64 arch_counter_get_cntvct_mem(void) return ((u64) vct_hi << 32) | vct_lo; } -static struct arch_timer_kvm_info arch_timer_kvm_info = { - .timecounter.cc.read = arch_counter_read_cc, - .timecounter.cc.mask = CLOCKSOURCE_MASK(56), -}; +static struct arch_timer_kvm_info arch_timer_kvm_info; struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) { @@ -923,7 +920,6 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) static void __init arch_counter_register(unsigned type) { u64 start_count; - struct cyclecounter *cc = _timer_kvm_info.timecounter.cc; /* Register the CP15 based counter if we have one */ if (type & ARCH_TIMER_TYPE_CP15) { @@ -943,9 +939,12 @@ static void __init arch_counter_register(unsigned type) start_count = arch_timer_read_counter(); clocksource_register_hz(_counter, arch_timer_rate); - cc->mult = clocksource_counter.mult; - cc->shift = clocksource_counter.shift; - timecounter_init(_timer_kvm_info.timecounter, start_count); + timecounter_initialize(_timer_kvm_info.timecounter, + arch_counter_read_cc, + CLOCKSOURCE_MASK(56), + clocksource_counter.mult, + clocksource_counter.shift, + start_count); /* 56 bits minimum, so we assume worst case rollover */ sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate); -- 1.9.1
[PATCH 04/27] clocksource/arm_arch_timer: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update arch_timer_kvm_info timecounter init with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Mark Rutland Cc: Marc Zyngier Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: linux-arm-ker...@lists.infradead.org Cc: linux-kernel@vger.kernel.org --- drivers/clocksource/arm_arch_timer.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 31543e5..d96393f 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -910,10 +910,7 @@ static u64 arch_counter_get_cntvct_mem(void) return ((u64) vct_hi << 32) | vct_lo; } -static struct arch_timer_kvm_info arch_timer_kvm_info = { - .timecounter.cc.read = arch_counter_read_cc, - .timecounter.cc.mask = CLOCKSOURCE_MASK(56), -}; +static struct arch_timer_kvm_info arch_timer_kvm_info; struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) { @@ -923,7 +920,6 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) static void __init arch_counter_register(unsigned type) { u64 start_count; - struct cyclecounter *cc = _timer_kvm_info.timecounter.cc; /* Register the CP15 based counter if we have one */ if (type & ARCH_TIMER_TYPE_CP15) { @@ -943,9 +939,12 @@ static void __init arch_counter_register(unsigned type) start_count = arch_timer_read_counter(); clocksource_register_hz(_counter, arch_timer_rate); - cc->mult = clocksource_counter.mult; - cc->shift = clocksource_counter.shift; - timecounter_init(_timer_kvm_info.timecounter, start_count); + timecounter_initialize(_timer_kvm_info.timecounter, + arch_counter_read_cc, + CLOCKSOURCE_MASK(56), + clocksource_counter.mult, + clocksource_counter.shift, + start_count); /* 56 bits minimum, so we assume worst case rollover */ sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate); -- 1.9.1
[PATCH 05/27] amd-xgbe: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update xgbe tstamp_tc timecounter init with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Tom Lendacky <thomas.lenda...@amd.com> Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c index 5ea4edf..486437b 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c @@ -228,7 +228,6 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata) { struct ptp_clock_info *info = >ptp_clock_info; struct ptp_clock *clock; - struct cyclecounter *cc = >tstamp_tc.cc; u64 dividend; snprintf(info->name, sizeof(info->name), "%s", @@ -258,12 +257,12 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata) pdata->tstamp_addend = div_u64(dividend, pdata->ptpclk_rate); /* Setup the timecounter */ - cc->read = xgbe_cc_read; - cc->mask = CLOCKSOURCE_MASK(64); - cc->mult = 1; - cc->shift = 0; - - timecounter_init(>tstamp_tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(>tstamp_tc, + xgbe_cc_read, + CLOCKSOURCE_MASK(64), + 1, + 0, + ktime_to_ns(ktime_get_real())); /* Disable all timestamping to start */ XGMAC_IOWRITE(pdata, MAC_TSCR, 0); -- 1.9.1
[PATCH 05/27] amd-xgbe: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update xgbe tstamp_tc timecounter init with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Tom Lendacky Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c index 5ea4edf..486437b 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c @@ -228,7 +228,6 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata) { struct ptp_clock_info *info = >ptp_clock_info; struct ptp_clock *clock; - struct cyclecounter *cc = >tstamp_tc.cc; u64 dividend; snprintf(info->name, sizeof(info->name), "%s", @@ -258,12 +257,12 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata) pdata->tstamp_addend = div_u64(dividend, pdata->ptpclk_rate); /* Setup the timecounter */ - cc->read = xgbe_cc_read; - cc->mask = CLOCKSOURCE_MASK(64); - cc->mult = 1; - cc->shift = 0; - - timecounter_init(>tstamp_tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(>tstamp_tc, + xgbe_cc_read, + CLOCKSOURCE_MASK(64), + 1, + 0, + ktime_to_ns(ktime_get_real())); /* Disable all timestamping to start */ XGMAC_IOWRITE(pdata, MAC_TSCR, 0); -- 1.9.1
[PATCH 07/27] fec: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update fec ethernet timecounter init with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Fugang Duan <fugang.d...@nxp.com> Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/freescale/fec_ptp.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index b1261d1..1ba7216 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -278,14 +278,13 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev) writel(FEC_T_CTRL_ENABLE | FEC_T_CTRL_PERIOD_RST, fep->hwp + FEC_ATIME_CTRL); - memset(>tc.cc, 0, sizeof(fep->tc.cc)); - fep->tc.cc.read = fec_ptp_read; - fep->tc.cc.mask = CLOCKSOURCE_MASK(31); - fep->tc.cc.shift = 31; - fep->tc.cc.mult = FEC_CC_MULT; - - /* reset the ns time counter */ - timecounter_init(>tc, ktime_to_ns(ktime_get_real())); + /* Initialize the ns time counter */ + timecounter_initialize(>tc, + fec_ptp_read, + CLOCKSOURCE_MASK(31), + FEC_CC_MULT, + 31, + ktime_to_ns(ktime_get_real())); spin_unlock_irqrestore(>tmreg_lock, flags); } -- 1.9.1
[PATCH 07/27] fec: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update fec ethernet timecounter init with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Fugang Duan Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/freescale/fec_ptp.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index b1261d1..1ba7216 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -278,14 +278,13 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev) writel(FEC_T_CTRL_ENABLE | FEC_T_CTRL_PERIOD_RST, fep->hwp + FEC_ATIME_CTRL); - memset(>tc.cc, 0, sizeof(fep->tc.cc)); - fep->tc.cc.read = fec_ptp_read; - fep->tc.cc.mask = CLOCKSOURCE_MASK(31); - fep->tc.cc.shift = 31; - fep->tc.cc.mult = FEC_CC_MULT; - - /* reset the ns time counter */ - timecounter_init(>tc, ktime_to_ns(ktime_get_real())); + /* Initialize the ns time counter */ + timecounter_initialize(>tc, + fec_ptp_read, + CLOCKSOURCE_MASK(31), + FEC_CC_MULT, + 31, + ktime_to_ns(ktime_get_real())); spin_unlock_irqrestore(>tmreg_lock, flags); } -- 1.9.1
[PATCH 08/27] e1000e: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update e1000e timecounter init with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Jeff Kirsher <jeffrey.t.kirs...@intel.com> Cc: intel-wired-...@lists.osuosl.org Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/intel/e1000e/e1000.h | 4 drivers/net/ethernet/intel/e1000e/netdev.c | 31 +- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index b59f82a..d6b0e59 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -341,6 +341,10 @@ struct e1000_adapter { struct work_struct tx_hwtstamp_work; spinlock_t systim_lock; /* protects SYSTIML/H regsters */ struct timecounter tc; + u64 (*cc_read)(const struct cyclecounter *cc); + u64 cc_mask; + u32 cc_mult; + u32 cc_shift; struct ptp_clock *ptp_clock; struct ptp_clock_info ptp_clock_info; struct pm_qos_request pm_qos_req; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index c9f7ba3..6be1327 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3536,7 +3536,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) incperiod = INCPERIOD_96MHZ; incvalue = INCVALUE_96MHZ; shift = INCVALUE_SHIFT_96MHZ; - adapter->tc.cc.shift = shift + INCPERIOD_SHIFT_96MHZ; + adapter->cc_shift = shift + INCPERIOD_SHIFT_96MHZ; break; case e1000_pch_lpt: if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) { @@ -3544,13 +3544,13 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) incperiod = INCPERIOD_96MHZ; incvalue = INCVALUE_96MHZ; shift = INCVALUE_SHIFT_96MHZ; - adapter->tc.cc.shift = shift + INCPERIOD_SHIFT_96MHZ; + adapter->cc_shift = shift + INCPERIOD_SHIFT_96MHZ; } else { /* Stable 25MHz frequency */ incperiod = INCPERIOD_25MHZ; incvalue = INCVALUE_25MHZ; shift = INCVALUE_SHIFT_25MHZ; - adapter->tc.cc.shift = shift; + adapter->cc_shift = shift; } break; case e1000_pch_spt: @@ -3559,7 +3559,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) incperiod = INCPERIOD_24MHZ; incvalue = INCVALUE_24MHZ; shift = INCVALUE_SHIFT_24MHZ; - adapter->tc.cc.shift = shift; + adapter->cc_shift = shift; break; } return -EINVAL; @@ -3569,13 +3569,13 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) incperiod = INCPERIOD_24MHZ; incvalue = INCVALUE_24MHZ; shift = INCVALUE_SHIFT_24MHZ; - adapter->tc.cc.shift = shift; + adapter->cc_shift = shift; } else { /* Stable 38400KHz frequency */ incperiod = INCPERIOD_38400KHZ; incvalue = INCVALUE_38400KHZ; shift = INCVALUE_SHIFT_38400KHZ; - adapter->tc.cc.shift = shift; + adapter->cc_shift = shift; } break; case e1000_82574: @@ -3584,7 +3584,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) incperiod = INCPERIOD_25MHZ; incvalue = INCVALUE_25MHZ; shift = INCVALUE_SHIFT_25MHZ; - adapter->tc.cc.shift = shift; + adapter->cc_shift = shift; break; default: return -EINVAL; @@ -3953,9 +3953,14 @@ static void e1000e_systim_reset(struct e1000_adapter *adapter) return; } - /* reset the systim ns time counter */ + /* reinitialize the systim ns time counter */ spin_lock_irqsave(>systim_lock, flags); - timecounter_init(>tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(>tc, + adapter->cc_read, + adapter->cc_mask, +
[PATCH 08/27] e1000e: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update e1000e timecounter init with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Jeff Kirsher Cc: intel-wired-...@lists.osuosl.org Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/intel/e1000e/e1000.h | 4 drivers/net/ethernet/intel/e1000e/netdev.c | 31 +- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index b59f82a..d6b0e59 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -341,6 +341,10 @@ struct e1000_adapter { struct work_struct tx_hwtstamp_work; spinlock_t systim_lock; /* protects SYSTIML/H regsters */ struct timecounter tc; + u64 (*cc_read)(const struct cyclecounter *cc); + u64 cc_mask; + u32 cc_mult; + u32 cc_shift; struct ptp_clock *ptp_clock; struct ptp_clock_info ptp_clock_info; struct pm_qos_request pm_qos_req; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index c9f7ba3..6be1327 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3536,7 +3536,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) incperiod = INCPERIOD_96MHZ; incvalue = INCVALUE_96MHZ; shift = INCVALUE_SHIFT_96MHZ; - adapter->tc.cc.shift = shift + INCPERIOD_SHIFT_96MHZ; + adapter->cc_shift = shift + INCPERIOD_SHIFT_96MHZ; break; case e1000_pch_lpt: if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) { @@ -3544,13 +3544,13 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) incperiod = INCPERIOD_96MHZ; incvalue = INCVALUE_96MHZ; shift = INCVALUE_SHIFT_96MHZ; - adapter->tc.cc.shift = shift + INCPERIOD_SHIFT_96MHZ; + adapter->cc_shift = shift + INCPERIOD_SHIFT_96MHZ; } else { /* Stable 25MHz frequency */ incperiod = INCPERIOD_25MHZ; incvalue = INCVALUE_25MHZ; shift = INCVALUE_SHIFT_25MHZ; - adapter->tc.cc.shift = shift; + adapter->cc_shift = shift; } break; case e1000_pch_spt: @@ -3559,7 +3559,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) incperiod = INCPERIOD_24MHZ; incvalue = INCVALUE_24MHZ; shift = INCVALUE_SHIFT_24MHZ; - adapter->tc.cc.shift = shift; + adapter->cc_shift = shift; break; } return -EINVAL; @@ -3569,13 +3569,13 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) incperiod = INCPERIOD_24MHZ; incvalue = INCVALUE_24MHZ; shift = INCVALUE_SHIFT_24MHZ; - adapter->tc.cc.shift = shift; + adapter->cc_shift = shift; } else { /* Stable 38400KHz frequency */ incperiod = INCPERIOD_38400KHZ; incvalue = INCVALUE_38400KHZ; shift = INCVALUE_SHIFT_38400KHZ; - adapter->tc.cc.shift = shift; + adapter->cc_shift = shift; } break; case e1000_82574: @@ -3584,7 +3584,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca) incperiod = INCPERIOD_25MHZ; incvalue = INCVALUE_25MHZ; shift = INCVALUE_SHIFT_25MHZ; - adapter->tc.cc.shift = shift; + adapter->cc_shift = shift; break; default: return -EINVAL; @@ -3953,9 +3953,14 @@ static void e1000e_systim_reset(struct e1000_adapter *adapter) return; } - /* reset the systim ns time counter */ + /* reinitialize the systim ns time counter */ spin_lock_irqsave(>systim_lock, flags); - timecounter_init(>tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(>tc, + adapter->cc_read, + adapter->cc_mask, + adapter->cc_mult, + adapter->cc_shift, +
[PATCH 03/27] microblaze: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update xilinx_tc init with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Michal Simek <mon...@monstr.eu> Cc: Daniel Lezcano <daniel.lezc...@linaro.org> Cc: Neil Armstrong <narmstr...@baylibre.com> Cc: Nicolai Stange <nicsta...@gmail.com> Cc: Arnd Bergmann <a...@arndb.de> Cc: Rob Herring <r...@kernel.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: linux-kernel@vger.kernel.org --- arch/microblaze/kernel/timer.c | 19 ++- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index b7f89e9..b32a896 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -204,20 +204,21 @@ static u64 xilinx_cc_read(const struct cyclecounter *cc) return xilinx_read(NULL); } -static struct timecounter xilinx_tc = { - .cc.read = xilinx_cc_read, - .cc.mask = CLOCKSOURCE_MASK(32), - .cc.mult = 0, - .cc.shift = 8, -}; +static struct timecounter xilinx_tc; static int __init init_xilinx_timecounter(void) { - struct cyclecounter *cc = _tc.cc; + u32 mult = 0; + u32 shift = 8; - cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift); + mult = div_sc(timer_clock_freq, NSEC_PER_SEC, shift); - timecounter_init(_tc, sched_clock()); + timecounter_initialize(_tc, + xilinx_cc_read, + CLOCKSOURCE_MASK(32), + mult, + shift, + sched_clock()); return 0; } -- 1.9.1
[PATCH 03/27] microblaze: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update xilinx_tc init with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Michal Simek Cc: Daniel Lezcano Cc: Neil Armstrong Cc: Nicolai Stange Cc: Arnd Bergmann Cc: Rob Herring Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org --- arch/microblaze/kernel/timer.c | 19 ++- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index b7f89e9..b32a896 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -204,20 +204,21 @@ static u64 xilinx_cc_read(const struct cyclecounter *cc) return xilinx_read(NULL); } -static struct timecounter xilinx_tc = { - .cc.read = xilinx_cc_read, - .cc.mask = CLOCKSOURCE_MASK(32), - .cc.mult = 0, - .cc.shift = 8, -}; +static struct timecounter xilinx_tc; static int __init init_xilinx_timecounter(void) { - struct cyclecounter *cc = _tc.cc; + u32 mult = 0; + u32 shift = 8; - cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift); + mult = div_sc(timer_clock_freq, NSEC_PER_SEC, shift); - timecounter_init(_tc, sched_clock()); + timecounter_initialize(_tc, + xilinx_cc_read, + CLOCKSOURCE_MASK(32), + mult, + shift, + sched_clock()); return 0; } -- 1.9.1
[PATCH 11/27] net/mlx4: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update mlx4 timecounter init with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Tariq Toukan <tar...@mellanox.com> Cc: net...@vger.kernel.org Cc: linux-r...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index 35987b5..dd736cc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c @@ -264,6 +264,7 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) { struct mlx4_dev *dev = mdev->dev; unsigned long flags; + u32 mult, shift; /* mlx4_en_init_timestamp is called for each netdev. * mdev->ptp_clock is common for all ports, skip initialization if @@ -274,17 +275,17 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) seqlock_init(>clock_lock); - memset(>clock.cc, 0, sizeof(mdev->clock.cc)); - mdev->clock.cc.read = mlx4_en_read_clock; - mdev->clock.cc.mask = CLOCKSOURCE_MASK(48); - mdev->clock.cc.shift = freq_to_shift(dev->caps.hca_core_clock); - mdev->clock.cc.mult = - clocksource_khz2mult(1000 * dev->caps.hca_core_clock, -mdev->clock.cc.shift); + shift = freq_to_shift(dev->caps.hca_core_clock); + mult = clocksource_khz2mult(1000 * dev->caps.hca_core_clock, shift); mdev->nominal_c_mult = mdev->clock.cc.mult; write_seqlock_irqsave(>clock_lock, flags); - timecounter_init(>clock, ktime_to_ns(ktime_get_real())); + timecounter_initialize(>clock, + mlx4_en_read_clock, + CLOCKSOURCE_MASK(48), + mult, + shift, + ktime_to_ns(ktime_get_real())); write_sequnlock_irqrestore(>clock_lock, flags); /* Configure the PHC */ -- 1.9.1
[PATCH 11/27] net/mlx4: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update mlx4 timecounter init with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Tariq Toukan Cc: net...@vger.kernel.org Cc: linux-r...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index 35987b5..dd736cc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c @@ -264,6 +264,7 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) { struct mlx4_dev *dev = mdev->dev; unsigned long flags; + u32 mult, shift; /* mlx4_en_init_timestamp is called for each netdev. * mdev->ptp_clock is common for all ports, skip initialization if @@ -274,17 +275,17 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) seqlock_init(>clock_lock); - memset(>clock.cc, 0, sizeof(mdev->clock.cc)); - mdev->clock.cc.read = mlx4_en_read_clock; - mdev->clock.cc.mask = CLOCKSOURCE_MASK(48); - mdev->clock.cc.shift = freq_to_shift(dev->caps.hca_core_clock); - mdev->clock.cc.mult = - clocksource_khz2mult(1000 * dev->caps.hca_core_clock, -mdev->clock.cc.shift); + shift = freq_to_shift(dev->caps.hca_core_clock); + mult = clocksource_khz2mult(1000 * dev->caps.hca_core_clock, shift); mdev->nominal_c_mult = mdev->clock.cc.mult; write_seqlock_irqsave(>clock_lock, flags); - timecounter_init(>clock, ktime_to_ns(ktime_get_real())); + timecounter_initialize(>clock, + mlx4_en_read_clock, + CLOCKSOURCE_MASK(48), + mult, + shift, + ktime_to_ns(ktime_get_real())); write_sequnlock_irqrestore(>clock_lock, flags); /* Configure the PHC */ -- 1.9.1
[PATCH 06/27] bnx2x: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update bnx2x timecounter init with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Ariel Elior <ariel.el...@cavium.com> Cc: everest-linux...@cavium.com Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 18 ++ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 83624ad..1e10a81 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -15269,15 +15269,6 @@ static u64 bnx2x_cyclecounter_read(const struct cyclecounter *cc) return phc_cycles; } -static void bnx2x_init_cyclecounter(struct cyclecounter *cc) -{ - memset(cc, 0, sizeof(*cc)); - cc->read = bnx2x_cyclecounter_read; - cc->mask = CYCLECOUNTER_MASK(64); - cc->shift = 0; - cc->mult = 1; -} - static int bnx2x_send_reset_timesync_ramrod(struct bnx2x *bp) { struct bnx2x_func_state_params func_params = {NULL}; @@ -15511,9 +15502,12 @@ void bnx2x_init_ptp(struct bnx2x *bp) * unload / load (e.g. MTU change) while it is running. */ if (!bp->timecounter_init_done) { - bnx2x_init_cyclecounter(>timecounter.cc); - timecounter_init(>timecounter, -ktime_to_ns(ktime_get_real())); + timecounter_initialize(>timecounter, + bnx2x_cyclecounter_read, + CYCLECOUNTER_MASK(64), + 1, + 0, + ktime_to_ns(ktime_get_real())); bp->timecounter_init_done = 1; } -- 1.9.1
[PATCH 06/27] bnx2x: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update bnx2x timecounter init with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Ariel Elior Cc: everest-linux...@cavium.com Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 18 ++ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 83624ad..1e10a81 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -15269,15 +15269,6 @@ static u64 bnx2x_cyclecounter_read(const struct cyclecounter *cc) return phc_cycles; } -static void bnx2x_init_cyclecounter(struct cyclecounter *cc) -{ - memset(cc, 0, sizeof(*cc)); - cc->read = bnx2x_cyclecounter_read; - cc->mask = CYCLECOUNTER_MASK(64); - cc->shift = 0; - cc->mult = 1; -} - static int bnx2x_send_reset_timesync_ramrod(struct bnx2x *bp) { struct bnx2x_func_state_params func_params = {NULL}; @@ -15511,9 +15502,12 @@ void bnx2x_init_ptp(struct bnx2x *bp) * unload / load (e.g. MTU change) while it is running. */ if (!bp->timecounter_init_done) { - bnx2x_init_cyclecounter(>timecounter.cc); - timecounter_init(>timecounter, -ktime_to_ns(ktime_get_real())); + timecounter_initialize(>timecounter, + bnx2x_cyclecounter_read, + CYCLECOUNTER_MASK(64), + 1, + 0, + ktime_to_ns(ktime_get_real())); bp->timecounter_init_done = 1; } -- 1.9.1
[PATCH 12/27] net/mlx5: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update mlx5 timecounter init with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Saeed Mahameed <sae...@mellanox.com> Cc: Matan Barak <mat...@mellanox.com> Cc: Leon Romanovsky <leo...@mellanox.com> Cc: Eugenia Emantayev <euge...@mellanox.com> Cc: Eitan Rabin <ra...@mellanox.com> Cc: Feras Daoud <fera...@mellanox.com> Cc: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Miroslav Lichvar <mlich...@redhat.com> Cc: net...@vger.kernel.org Cc: linux-r...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 18 +++--- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index 8cb6838..071f78a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -458,6 +458,7 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev) u64 ns; u64 frac = 0; u32 dev_freq; + u32 mult, shift; dev_freq = MLX5_CAP_GEN(mdev, device_frequency_khz); if (!dev_freq) { @@ -465,13 +466,16 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev) return; } rwlock_init(>lock); - cc->read = read_internal_timer; - cc->shift = MLX5_CYCLES_SHIFT; - cc->mult = clocksource_khz2mult(dev_freq, cc->shift); - clock->nominal_c_mult = cc->mult; - cc->mask = CLOCKSOURCE_MASK(41); - - timecounter_init(>tc, ktime_to_ns(ktime_get_real())); + shift = MLX5_CYCLES_SHIFT; + mult = clocksource_khz2mult(dev_freq, shift); + clock->nominal_c_mult = mult; + + timecounter_initialize(>tc, + read_internal_timer, + CLOCKSOURCE_MASK(41), + mult, + shift, + ktime_to_ns(ktime_get_real())); /* Calculate period in seconds to call the overflow watchdog - to make * sure counter is checked at least once every wrap around. -- 1.9.1
[PATCH 12/27] net/mlx5: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update mlx5 timecounter init with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Saeed Mahameed Cc: Matan Barak Cc: Leon Romanovsky Cc: Eugenia Emantayev Cc: Eitan Rabin Cc: Feras Daoud Cc: Sagar Arun Kamble Cc: Miroslav Lichvar Cc: net...@vger.kernel.org Cc: linux-r...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 18 +++--- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index 8cb6838..071f78a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -458,6 +458,7 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev) u64 ns; u64 frac = 0; u32 dev_freq; + u32 mult, shift; dev_freq = MLX5_CAP_GEN(mdev, device_frequency_khz); if (!dev_freq) { @@ -465,13 +466,16 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev) return; } rwlock_init(>lock); - cc->read = read_internal_timer; - cc->shift = MLX5_CYCLES_SHIFT; - cc->mult = clocksource_khz2mult(dev_freq, cc->shift); - clock->nominal_c_mult = cc->mult; - cc->mask = CLOCKSOURCE_MASK(41); - - timecounter_init(>tc, ktime_to_ns(ktime_get_real())); + shift = MLX5_CYCLES_SHIFT; + mult = clocksource_khz2mult(dev_freq, shift); + clock->nominal_c_mult = mult; + + timecounter_initialize(>tc, + read_internal_timer, + CLOCKSOURCE_MASK(41), + mult, + shift, + ktime_to_ns(ktime_get_real())); /* Calculate period in seconds to call the overflow watchdog - to make * sure counter is checked at least once every wrap around. -- 1.9.1
[PATCH 15/27] ALSA: hda - Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update azx timecounter init with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Jaroslav Kysela <pe...@perex.cz> Cc: Takashi Iwai <ti...@suse.com> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Vinod Koul <vinod.k...@intel.com> Cc: alsa-de...@alsa-project.org Cc: linux-kernel@vger.kernel.org --- sound/hda/hdac_stream.c | 14 ++ 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index 9426c1a..ad91dde 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -477,12 +477,8 @@ static void azx_timecounter_init(struct hdac_stream *azx_dev, bool force, u64 last) { struct timecounter *tc = _dev->tc; - struct cyclecounter *cc = _dev->tc.cc; u64 nsec; - cc->read = azx_cc_read; - cc->mask = CLOCKSOURCE_MASK(32); - /* * Converting from 24 MHz to ns means applying a 125/3 factor. * To avoid any saturation issues in intermediate operations, @@ -493,11 +489,13 @@ static void azx_timecounter_init(struct hdac_stream *azx_dev, * overflows occur after about 4 hours or less, not a option. */ - cc->mult = 125; /* saturation after 195 years */ - cc->shift = 0; - nsec = 0; /* audio time is elapsed time since trigger */ - timecounter_init(tc, nsec); + timecounter_initialize(tc, + azx_cc_read, + CLOCKSOURCE_MASK(32), + 125, /* saturation after 195 years */ + 0, + nsec); if (force) { /* * force timecounter to use predefined value, -- 1.9.1
[PATCH 15/27] ALSA: hda - Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update azx timecounter init with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: Thomas Gleixner Cc: Vinod Koul Cc: alsa-de...@alsa-project.org Cc: linux-kernel@vger.kernel.org --- sound/hda/hdac_stream.c | 14 ++ 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index 9426c1a..ad91dde 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -477,12 +477,8 @@ static void azx_timecounter_init(struct hdac_stream *azx_dev, bool force, u64 last) { struct timecounter *tc = _dev->tc; - struct cyclecounter *cc = _dev->tc.cc; u64 nsec; - cc->read = azx_cc_read; - cc->mask = CLOCKSOURCE_MASK(32); - /* * Converting from 24 MHz to ns means applying a 125/3 factor. * To avoid any saturation issues in intermediate operations, @@ -493,11 +489,13 @@ static void azx_timecounter_init(struct hdac_stream *azx_dev, * overflows occur after about 4 hours or less, not a option. */ - cc->mult = 125; /* saturation after 195 years */ - cc->shift = 0; - nsec = 0; /* audio time is elapsed time since trigger */ - timecounter_init(tc, nsec); + timecounter_initialize(tc, + azx_cc_read, + CLOCKSOURCE_MASK(32), + 125, /* saturation after 195 years */ + 0, + nsec); if (force) { /* * force timecounter to use predefined value, -- 1.9.1
[PATCH 14/27] net: cpts: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update cpts timecounter init with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: "David S. Miller" <da...@davemloft.net> Cc: Grygorii Strashko <grygorii.stras...@ti.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Bhumika Goyal <bhumi...@gmail.com> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Ivan Khoronzhuk <ivan.khoronz...@linaro.org> Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/ti/cpts.c | 29 + drivers/net/ethernet/ti/cpts.h | 3 +++ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c index b8fe843..e6afc94 100644 --- a/drivers/net/ethernet/ti/cpts.c +++ b/drivers/net/ethernet/ti/cpts.c @@ -447,7 +447,12 @@ int cpts_register(struct cpts *cpts) cpts_write32(cpts, CPTS_EN, control); cpts_write32(cpts, TS_PEND_EN, int_enable); - timecounter_init(>tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(>tc, + cpts_systim_read, + cpts->mask, + cpts->mult, + cpts->shift, + ktime_to_ns(ktime_get_real())); cpts->clock = ptp_clock_register(>info, cpts->dev); if (IS_ERR(cpts->clock)) { @@ -484,7 +489,8 @@ void cpts_unregister(struct cpts *cpts) } EXPORT_SYMBOL_GPL(cpts_unregister); -static void cpts_calc_mult_shift(struct cpts *cpts) +static void cpts_calc_mult_shift(struct cpts *cpts, u64 mask, +u32 *mult, u32 *shift) { struct cyclecounter *cc = >tc.cc; u64 frac, maxsec, ns; @@ -495,7 +501,7 @@ static void cpts_calc_mult_shift(struct cpts *cpts) /* Calc the maximum number of seconds which we can run before * wrapping around. */ - maxsec = cc->mask; + maxsec = mask; do_div(maxsec, freq); /* limit conversation rate to 10 sec as higher values will produce * too small mult factors and so reduce the conversion accuracy @@ -508,18 +514,18 @@ static void cpts_calc_mult_shift(struct cpts *cpts) dev_info(cpts->dev, "cpts: overflow check period %lu (jiffies)\n", cpts->ov_check_period); - if (cc->mult || cc->shift) + if (*mult || *shift) return; - clocks_calc_mult_shift(>mult, >shift, + clocks_calc_mult_shift(mult, shift, freq, NSEC_PER_SEC, maxsec); frac = 0; - ns = cyclecounter_cyc2ns(cc, freq, cc->mask, ); + ns = cyclecounter_cyc2ns(cc, freq, mask, ); dev_info(cpts->dev, "CPTS: ref_clk_freq:%u calc_mult:%u calc_shift:%u error:%lld nsec/sec\n", -freq, cc->mult, cc->shift, +freq, *mult, *shift, (ns - NSEC_PER_SEC)); } @@ -571,15 +577,14 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs, clk_prepare(cpts->refclk); - cpts->tc.cc.read = cpts_systim_read; - cpts->tc.cc.mask = CLOCKSOURCE_MASK(32); + cpts->mask = CLOCKSOURCE_MASK(32); cpts->info = cpts_info; - cpts_calc_mult_shift(cpts); - /* save tc.cc.mult original value as it can be modified + cpts_calc_mult_shift(cpts, cpts->mask, >mult, >shift); + /* save mult original value as it can be modified * by cpts_ptp_adjfreq(). */ - cpts->cc_mult = cpts->tc.cc.mult; + cpts->cc_mult = cpts->mult; return cpts; } diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h index a7174eb..da50d34 100644 --- a/drivers/net/ethernet/ti/cpts.h +++ b/drivers/net/ethernet/ti/cpts.h @@ -118,6 +118,9 @@ struct cpts { spinlock_t lock; /* protects time registers */ u32 cc_mult; /* for the nominal frequency */ struct timecounter tc; + u64 mask; + u32 mult; + u32 shift; int phc_index; struct clk *refclk; struct list_head events; -- 1.9.1
[PATCH 14/27] net: cpts: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update cpts timecounter init with this new function. Signed-off-by: Sagar Arun Kamble Cc: "David S. Miller" Cc: Grygorii Strashko Cc: Richard Cochran Cc: Bhumika Goyal Cc: Thomas Gleixner Cc: Ivan Khoronzhuk Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/ti/cpts.c | 29 + drivers/net/ethernet/ti/cpts.h | 3 +++ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c index b8fe843..e6afc94 100644 --- a/drivers/net/ethernet/ti/cpts.c +++ b/drivers/net/ethernet/ti/cpts.c @@ -447,7 +447,12 @@ int cpts_register(struct cpts *cpts) cpts_write32(cpts, CPTS_EN, control); cpts_write32(cpts, TS_PEND_EN, int_enable); - timecounter_init(>tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(>tc, + cpts_systim_read, + cpts->mask, + cpts->mult, + cpts->shift, + ktime_to_ns(ktime_get_real())); cpts->clock = ptp_clock_register(>info, cpts->dev); if (IS_ERR(cpts->clock)) { @@ -484,7 +489,8 @@ void cpts_unregister(struct cpts *cpts) } EXPORT_SYMBOL_GPL(cpts_unregister); -static void cpts_calc_mult_shift(struct cpts *cpts) +static void cpts_calc_mult_shift(struct cpts *cpts, u64 mask, +u32 *mult, u32 *shift) { struct cyclecounter *cc = >tc.cc; u64 frac, maxsec, ns; @@ -495,7 +501,7 @@ static void cpts_calc_mult_shift(struct cpts *cpts) /* Calc the maximum number of seconds which we can run before * wrapping around. */ - maxsec = cc->mask; + maxsec = mask; do_div(maxsec, freq); /* limit conversation rate to 10 sec as higher values will produce * too small mult factors and so reduce the conversion accuracy @@ -508,18 +514,18 @@ static void cpts_calc_mult_shift(struct cpts *cpts) dev_info(cpts->dev, "cpts: overflow check period %lu (jiffies)\n", cpts->ov_check_period); - if (cc->mult || cc->shift) + if (*mult || *shift) return; - clocks_calc_mult_shift(>mult, >shift, + clocks_calc_mult_shift(mult, shift, freq, NSEC_PER_SEC, maxsec); frac = 0; - ns = cyclecounter_cyc2ns(cc, freq, cc->mask, ); + ns = cyclecounter_cyc2ns(cc, freq, mask, ); dev_info(cpts->dev, "CPTS: ref_clk_freq:%u calc_mult:%u calc_shift:%u error:%lld nsec/sec\n", -freq, cc->mult, cc->shift, +freq, *mult, *shift, (ns - NSEC_PER_SEC)); } @@ -571,15 +577,14 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs, clk_prepare(cpts->refclk); - cpts->tc.cc.read = cpts_systim_read; - cpts->tc.cc.mask = CLOCKSOURCE_MASK(32); + cpts->mask = CLOCKSOURCE_MASK(32); cpts->info = cpts_info; - cpts_calc_mult_shift(cpts); - /* save tc.cc.mult original value as it can be modified + cpts_calc_mult_shift(cpts, cpts->mask, >mult, >shift); + /* save mult original value as it can be modified * by cpts_ptp_adjfreq(). */ - cpts->cc_mult = cpts->tc.cc.mult; + cpts->cc_mult = cpts->mult; return cpts; } diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h index a7174eb..da50d34 100644 --- a/drivers/net/ethernet/ti/cpts.h +++ b/drivers/net/ethernet/ti/cpts.h @@ -118,6 +118,9 @@ struct cpts { spinlock_t lock; /* protects time registers */ u32 cc_mult; /* for the nominal frequency */ struct timecounter tc; + u64 mask; + u32 mult; + u32 shift; int phc_index; struct clk *refclk; struct list_head events; -- 1.9.1
[PATCH 18/27] bnx2x: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update bnx2x_ptp_settime with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Ariel Elior <ariel.el...@cavium.com> Cc: everest-linux...@cavium.com Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 1e10a81..e30e736 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -13849,8 +13849,8 @@ static int bnx2x_ptp_settime(struct ptp_clock_info *ptp, DP(BNX2X_MSG_PTP, "PTP settime called, ns = %llu\n", ns); - /* Re-init the timecounter */ - timecounter_init(>timecounter, ns); + /* Reset the timecounter */ + timecounter_reset(>timecounter, ns); return 0; } -- 1.9.1
[PATCH 16/27] timecounter: Introduce timecounter_reset
timecounter_init initializes the cyclecounter and sets the start time. Sometimes drivers using timecounter just want to update start time. This patch creates new function timecounter_reset that just resets the timecounter start time and associated state. Suggested-by: Richard Cochran <richardcoch...@gmail.com> Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Chris Wilson <ch...@chris-wilson.co.uk> Cc: John Stultz <john.stu...@linaro.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Stephen Boyd <sb...@codeaurora.org> Cc: linux-kernel@vger.kernel.org --- include/linux/timecounter.h | 17 +++-- kernel/time/timecounter.c | 9 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h index 59d3fd7..e0fd741 100644 --- a/include/linux/timecounter.h +++ b/include/linux/timecounter.h @@ -98,7 +98,7 @@ static inline void timecounter_adjtime(struct timecounter *tc, s64 delta) /** * timecounter_init - initialize a time counter - * @tc:Pointer to time counter which is to be initialized/reset + * @tc:Pointer to time counter which is to be initialized * @start_tstamp: Arbitrary initial time stamp. * * After this call the current cycle register (roughly) corresponds to @@ -131,8 +131,21 @@ extern void timecounter_initialize(struct timecounter *tc, u64 start_tstamp); /** + * timecounter_reset - reset a time counter + * @tc:Pointer to time counter which is to be reset + * @start_tstamp: Arbitrary initial time stamp. + * + * After this call the current cycle register (roughly) corresponds to + * the supplied time stamp. Every call to timecounter_read() increments + * the time stamp counter by the number of elapsed nanoseconds. + */ +extern void timecounter_reset(struct timecounter *tc, + u64 start_tstamp); + +/** * timecounter_read - return nanoseconds elapsed since timecounter_init() or - *timecounter_initialize() plus the initial time stamp + *timecounter_initialize() or timecounter_reset() plus + * the initial time stamp * @tc: Pointer to time counter. * * In other words, keeps track of time since the same epoch as diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c index 6d915752..3f62fe0 100644 --- a/kernel/time/timecounter.c +++ b/kernel/time/timecounter.c @@ -47,6 +47,15 @@ void timecounter_initialize(struct timecounter *tc, } EXPORT_SYMBOL_GPL(timecounter_initialize); +void timecounter_reset(struct timecounter *tc, + u64 start_tstamp) +{ + tc->cycle_last = tc->cc.read(>cc); + tc->nsec = start_tstamp; + tc->frac = 0; +} +EXPORT_SYMBOL_GPL(timecounter_reset); + /** * timecounter_read_delta - get nanoseconds since last call of this function * @tc: Pointer to time counter -- 1.9.1
[PATCH 18/27] bnx2x: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update bnx2x_ptp_settime with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Ariel Elior Cc: everest-linux...@cavium.com Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 1e10a81..e30e736 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -13849,8 +13849,8 @@ static int bnx2x_ptp_settime(struct ptp_clock_info *ptp, DP(BNX2X_MSG_PTP, "PTP settime called, ns = %llu\n", ns); - /* Re-init the timecounter */ - timecounter_init(>timecounter, ns); + /* Reset the timecounter */ + timecounter_reset(>timecounter, ns); return 0; } -- 1.9.1
[PATCH 16/27] timecounter: Introduce timecounter_reset
timecounter_init initializes the cyclecounter and sets the start time. Sometimes drivers using timecounter just want to update start time. This patch creates new function timecounter_reset that just resets the timecounter start time and associated state. Suggested-by: Richard Cochran Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Chris Wilson Cc: John Stultz Cc: Thomas Gleixner Cc: Stephen Boyd Cc: linux-kernel@vger.kernel.org --- include/linux/timecounter.h | 17 +++-- kernel/time/timecounter.c | 9 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h index 59d3fd7..e0fd741 100644 --- a/include/linux/timecounter.h +++ b/include/linux/timecounter.h @@ -98,7 +98,7 @@ static inline void timecounter_adjtime(struct timecounter *tc, s64 delta) /** * timecounter_init - initialize a time counter - * @tc:Pointer to time counter which is to be initialized/reset + * @tc:Pointer to time counter which is to be initialized * @start_tstamp: Arbitrary initial time stamp. * * After this call the current cycle register (roughly) corresponds to @@ -131,8 +131,21 @@ extern void timecounter_initialize(struct timecounter *tc, u64 start_tstamp); /** + * timecounter_reset - reset a time counter + * @tc:Pointer to time counter which is to be reset + * @start_tstamp: Arbitrary initial time stamp. + * + * After this call the current cycle register (roughly) corresponds to + * the supplied time stamp. Every call to timecounter_read() increments + * the time stamp counter by the number of elapsed nanoseconds. + */ +extern void timecounter_reset(struct timecounter *tc, + u64 start_tstamp); + +/** * timecounter_read - return nanoseconds elapsed since timecounter_init() or - *timecounter_initialize() plus the initial time stamp + *timecounter_initialize() or timecounter_reset() plus + * the initial time stamp * @tc: Pointer to time counter. * * In other words, keeps track of time since the same epoch as diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c index 6d915752..3f62fe0 100644 --- a/kernel/time/timecounter.c +++ b/kernel/time/timecounter.c @@ -47,6 +47,15 @@ void timecounter_initialize(struct timecounter *tc, } EXPORT_SYMBOL_GPL(timecounter_initialize); +void timecounter_reset(struct timecounter *tc, + u64 start_tstamp) +{ + tc->cycle_last = tc->cc.read(>cc); + tc->nsec = start_tstamp; + tc->frac = 0; +} +EXPORT_SYMBOL_GPL(timecounter_reset); + /** * timecounter_read_delta - get nanoseconds since last call of this function * @tc: Pointer to time counter -- 1.9.1
[PATCH 22/27] ixgbe: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update ixgbe_ptp_settime with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Jeff Kirsher <jeffrey.t.kirs...@intel.com> Cc: intel-wired-...@lists.osuosl.org Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 073c1ef..35f85ef 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -508,7 +508,7 @@ static int ixgbe_ptp_settime(struct ptp_clock_info *ptp, /* reset the timecounter */ spin_lock_irqsave(>tmreg_lock, flags); - timecounter_init(>hw_tc, ns); + timecounter_reset(>hw_tc, ns); spin_unlock_irqrestore(>tmreg_lock, flags); if (adapter->ptp_setup_sdp) -- 1.9.1
[PATCH 22/27] ixgbe: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update ixgbe_ptp_settime with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Jeff Kirsher Cc: intel-wired-...@lists.osuosl.org Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 073c1ef..35f85ef 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -508,7 +508,7 @@ static int ixgbe_ptp_settime(struct ptp_clock_info *ptp, /* reset the timecounter */ spin_lock_irqsave(>tmreg_lock, flags); - timecounter_init(>hw_tc, ns); + timecounter_reset(>hw_tc, ns); spin_unlock_irqrestore(>tmreg_lock, flags); if (adapter->ptp_setup_sdp) -- 1.9.1
[PATCH 23/27] net/mlx4: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update mlx4_en_phc_settime with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Tariq Toukan <tar...@mellanox.com> Cc: net...@vger.kernel.org Cc: linux-r...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index dd736cc..bfed4ac 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c @@ -207,7 +207,7 @@ static int mlx4_en_phc_settime(struct ptp_clock_info *ptp, /* reset the timecounter */ write_seqlock_irqsave(>clock_lock, flags); - timecounter_init(>clock, ns); + timecounter_reset(>clock, ns); write_sequnlock_irqrestore(>clock_lock, flags); return 0; -- 1.9.1
[PATCH 21/27] igb: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update igb_ptp_settime_82576 with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Jeff Kirsher <jeffrey.t.kirs...@intel.com> Cc: intel-wired-...@lists.osuosl.org Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/intel/igb/igb_ptp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index f6c1a8d..90344b2 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -330,7 +330,7 @@ static int igb_ptp_settime_82576(struct ptp_clock_info *ptp, spin_lock_irqsave(>tmreg_lock, flags); - timecounter_init(>tc, ns); + timecounter_reset(>tc, ns); spin_unlock_irqrestore(>tmreg_lock, flags); -- 1.9.1
[PATCH 21/27] igb: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update igb_ptp_settime_82576 with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Jeff Kirsher Cc: intel-wired-...@lists.osuosl.org Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/intel/igb/igb_ptp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index f6c1a8d..90344b2 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -330,7 +330,7 @@ static int igb_ptp_settime_82576(struct ptp_clock_info *ptp, spin_lock_irqsave(>tmreg_lock, flags); - timecounter_init(>tc, ns); + timecounter_reset(>tc, ns); spin_unlock_irqrestore(>tmreg_lock, flags); -- 1.9.1
[PATCH 23/27] net/mlx4: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update mlx4_en_phc_settime with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Tariq Toukan Cc: net...@vger.kernel.org Cc: linux-r...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index dd736cc..bfed4ac 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c @@ -207,7 +207,7 @@ static int mlx4_en_phc_settime(struct ptp_clock_info *ptp, /* reset the timecounter */ write_seqlock_irqsave(>clock_lock, flags); - timecounter_init(>clock, ns); + timecounter_reset(>clock, ns); write_sequnlock_irqrestore(>clock_lock, flags); return 0; -- 1.9.1
[PATCH 24/27] net/mlx5: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update mlx5_ptp_settime with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Saeed Mahameed <sae...@mellanox.com> Cc: Matan Barak <mat...@mellanox.com> Cc: Leon Romanovsky <leo...@mellanox.com> Cc: Eugenia Emantayev <euge...@mellanox.com> Cc: Eitan Rabin <ra...@mellanox.com> Cc: Feras Daoud <fera...@mellanox.com> Cc: Tariq Toukan <tar...@mellanox.com> Cc: Thomas Gleixner <t...@linutronix.de> Cc: net...@vger.kernel.org Cc: linux-r...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index 071f78a..e490522 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -122,7 +122,7 @@ static int mlx5_ptp_settime(struct ptp_clock_info *ptp, unsigned long flags; write_lock_irqsave(>lock, flags); - timecounter_init(>tc, ns); + timecounter_reset(>tc, ns); write_unlock_irqrestore(>lock, flags); return 0; -- 1.9.1
[PATCH 24/27] net/mlx5: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update mlx5_ptp_settime with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Saeed Mahameed Cc: Matan Barak Cc: Leon Romanovsky Cc: Eugenia Emantayev Cc: Eitan Rabin Cc: Feras Daoud Cc: Tariq Toukan Cc: Thomas Gleixner Cc: net...@vger.kernel.org Cc: linux-r...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index 071f78a..e490522 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -122,7 +122,7 @@ static int mlx5_ptp_settime(struct ptp_clock_info *ptp, unsigned long flags; write_lock_irqsave(>lock, flags); - timecounter_init(>tc, ns); + timecounter_reset(>tc, ns); write_unlock_irqrestore(>lock, flags); return 0; -- 1.9.1
[PATCH 25/27] qede: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update qede_ptp_settime with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Ariel Elior <ariel.el...@cavium.com> Cc: everest-linux...@cavium.com Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/qlogic/qede/qede_ptp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c b/drivers/net/ethernet/qlogic/qede/qede_ptp.c index 0d054dc..c2de311 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c +++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c @@ -129,9 +129,9 @@ static int qede_ptp_settime(struct ptp_clock_info *info, DP_VERBOSE(edev, QED_MSG_DEBUG, "PTP settime called, ns = %llu\n", ns); - /* Re-init the timecounter */ + /* Reset the timecounter */ spin_lock_bh(>lock); - timecounter_init(>tc, ns); + timecounter_reset(>tc, ns); spin_unlock_bh(>lock); return 0; -- 1.9.1
[PATCH 26/27] net: cpts: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update cpts_ptp_settime with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: "David S. Miller" <da...@davemloft.net> Cc: Grygorii Strashko <grygorii.stras...@ti.com> Cc: Bhumika Goyal <bhumi...@gmail.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Thomas Gleixner <t...@linutronix.de> Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/ti/cpts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c index e6afc94..41bac4d 100644 --- a/drivers/net/ethernet/ti/cpts.c +++ b/drivers/net/ethernet/ti/cpts.c @@ -268,7 +268,7 @@ static int cpts_ptp_settime(struct ptp_clock_info *ptp, ns = timespec64_to_ns(ts); spin_lock_irqsave(>lock, flags); - timecounter_init(>tc, ns); + timecounter_reset(>tc, ns); spin_unlock_irqrestore(>lock, flags); return 0; -- 1.9.1
[PATCH 25/27] qede: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update qede_ptp_settime with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Ariel Elior Cc: everest-linux...@cavium.com Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/qlogic/qede/qede_ptp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c b/drivers/net/ethernet/qlogic/qede/qede_ptp.c index 0d054dc..c2de311 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c +++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c @@ -129,9 +129,9 @@ static int qede_ptp_settime(struct ptp_clock_info *info, DP_VERBOSE(edev, QED_MSG_DEBUG, "PTP settime called, ns = %llu\n", ns); - /* Re-init the timecounter */ + /* Reset the timecounter */ spin_lock_bh(>lock); - timecounter_init(>tc, ns); + timecounter_reset(>tc, ns); spin_unlock_bh(>lock); return 0; -- 1.9.1
[PATCH 26/27] net: cpts: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update cpts_ptp_settime with this new function. Signed-off-by: Sagar Arun Kamble Cc: "David S. Miller" Cc: Grygorii Strashko Cc: Bhumika Goyal Cc: Richard Cochran Cc: Thomas Gleixner Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/ti/cpts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c index e6afc94..41bac4d 100644 --- a/drivers/net/ethernet/ti/cpts.c +++ b/drivers/net/ethernet/ti/cpts.c @@ -268,7 +268,7 @@ static int cpts_ptp_settime(struct ptp_clock_info *ptp, ns = timespec64_to_ns(ts); spin_lock_irqsave(>lock, flags); - timecounter_init(>tc, ns); + timecounter_reset(>tc, ns); spin_unlock_irqrestore(>lock, flags); return 0; -- 1.9.1
[PATCH 20/27] e1000e: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update e1000e_phc_settime with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Jeff Kirsher <jeffrey.t.kirs...@intel.com> Cc: intel-wired-...@lists.osuosl.org Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/intel/e1000e/ptp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c b/drivers/net/ethernet/intel/e1000e/ptp.c index 03d5f2a..5b368aa 100644 --- a/drivers/net/ethernet/intel/e1000e/ptp.c +++ b/drivers/net/ethernet/intel/e1000e/ptp.c @@ -222,7 +222,7 @@ static int e1000e_phc_settime(struct ptp_clock_info *ptp, /* reset the timecounter */ spin_lock_irqsave(>systim_lock, flags); - timecounter_init(>tc, ns); + timecounter_reset(>tc, ns); spin_unlock_irqrestore(>systim_lock, flags); return 0; -- 1.9.1
[PATCH 20/27] e1000e: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update e1000e_phc_settime with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Jeff Kirsher Cc: intel-wired-...@lists.osuosl.org Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/intel/e1000e/ptp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/e1000e/ptp.c b/drivers/net/ethernet/intel/e1000e/ptp.c index 03d5f2a..5b368aa 100644 --- a/drivers/net/ethernet/intel/e1000e/ptp.c +++ b/drivers/net/ethernet/intel/e1000e/ptp.c @@ -222,7 +222,7 @@ static int e1000e_phc_settime(struct ptp_clock_info *ptp, /* reset the timecounter */ spin_lock_irqsave(>systim_lock, flags); - timecounter_init(>tc, ns); + timecounter_reset(>tc, ns); spin_unlock_irqrestore(>systim_lock, flags); return 0; -- 1.9.1
[PATCH 17/27] amd-xgbe: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update xgbe_config_tstamp and xgbe_settime with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Tom Lendacky <thomas.lenda...@amd.com> Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 4 ++-- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 5005c87..aee99de 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -1621,8 +1621,8 @@ static int xgbe_config_tstamp(struct xgbe_prv_data *pdata, xgbe_update_tstamp_addend(pdata, pdata->tstamp_addend); xgbe_set_tstamp_time(pdata, 0, 0); - /* Initialize the timecounter */ - timecounter_init(>tstamp_tc, ktime_to_ns(ktime_get_real())); + /* Reset the timecounter */ + timecounter_reset(>tstamp_tc, ktime_to_ns(ktime_get_real())); return 0; } diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c index 486437b..5fcde50 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c @@ -211,7 +211,7 @@ static int xgbe_settime(struct ptp_clock_info *info, spin_lock_irqsave(>tstamp_lock, flags); - timecounter_init(>tstamp_tc, nsec); + timecounter_reset(>tstamp_tc, nsec); spin_unlock_irqrestore(>tstamp_lock, flags); -- 1.9.1
[PATCH 27/27] timecounter: Remove timecounter_init
With all timecounter users now initializing timecounter using timecounter_initialize remove timecounter_init function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: John Stultz <john.stu...@linaro.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Stephen Boyd <sb...@codeaurora.org> Cc: linux-kernel@vger.kernel.org --- include/linux/timecounter.h | 20 +++- kernel/time/timecounter.c | 16 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h index e0fd741..e3e1d1e 100644 --- a/include/linux/timecounter.h +++ b/include/linux/timecounter.h @@ -46,8 +46,7 @@ struct cyclecounter { /** * struct timecounter - layer above a %struct cyclecounter which counts nanoseconds * Contains the state needed by timecounter_read() to detect - * cycle counter wrap around. Initialize with timecounter_init() when - * underlying cyclecounter is initialized, with timecounter_initialize() to + * cycle counter wrap around. Initialize with timecounter_initialize() to * initialize cyclecounter and timecounter fields. Also used to convert * cycle counts into the corresponding nanosecond counts with * timecounter_cyc2time(). Users of this code are responsible for @@ -97,18 +96,6 @@ static inline void timecounter_adjtime(struct timecounter *tc, s64 delta) } /** - * timecounter_init - initialize a time counter - * @tc:Pointer to time counter which is to be initialized - * @start_tstamp: Arbitrary initial time stamp. - * - * After this call the current cycle register (roughly) corresponds to - * the initial time stamp. Every call to timecounter_read() increments - * the time stamp counter by the number of elapsed nanoseconds. - */ -extern void timecounter_init(struct timecounter *tc, -u64 start_tstamp); - -/** * timecounter_initialize - initialize a time counter and underlying cyclecounter * @tc:Pointer to time counter which is to be initialized @@ -143,9 +130,8 @@ extern void timecounter_reset(struct timecounter *tc, u64 start_tstamp); /** - * timecounter_read - return nanoseconds elapsed since timecounter_init() or - *timecounter_initialize() or timecounter_reset() plus - * the initial time stamp + * timecounter_read - return nanoseconds elapsed since timecounter_initialize() + * or timecounter_reset() plus the initial time stamp * @tc: Pointer to time counter. * * In other words, keeps track of time since the same epoch as diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c index 3f62fe0..0a02ef0 100644 --- a/kernel/time/timecounter.c +++ b/kernel/time/timecounter.c @@ -18,17 +18,6 @@ #include #include -void timecounter_init(struct timecounter *tc, u64 start_tstamp) -{ - struct cyclecounter *cc = >cc; - - tc->cycle_last = cc->read(cc); - tc->nsec = start_tstamp; - tc->mask = (1ULL << cc->shift) - 1; - tc->frac = 0; -} -EXPORT_SYMBOL_GPL(timecounter_init); - void timecounter_initialize(struct timecounter *tc, u64 (*read)(const struct cyclecounter *cc), u64 mask, @@ -43,7 +32,10 @@ void timecounter_initialize(struct timecounter *tc, cc->mult = mult; cc->shift = shift; - timecounter_init(tc, start_tstamp); + tc->cycle_last = cc->read(cc); + tc->nsec = start_tstamp; + tc->mask = (1ULL << cc->shift) - 1; + tc->frac = 0; } EXPORT_SYMBOL_GPL(timecounter_initialize); -- 1.9.1
[PATCH 17/27] amd-xgbe: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update xgbe_config_tstamp and xgbe_settime with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Tom Lendacky Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 4 ++-- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 5005c87..aee99de 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -1621,8 +1621,8 @@ static int xgbe_config_tstamp(struct xgbe_prv_data *pdata, xgbe_update_tstamp_addend(pdata, pdata->tstamp_addend); xgbe_set_tstamp_time(pdata, 0, 0); - /* Initialize the timecounter */ - timecounter_init(>tstamp_tc, ktime_to_ns(ktime_get_real())); + /* Reset the timecounter */ + timecounter_reset(>tstamp_tc, ktime_to_ns(ktime_get_real())); return 0; } diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c index 486437b..5fcde50 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-ptp.c @@ -211,7 +211,7 @@ static int xgbe_settime(struct ptp_clock_info *info, spin_lock_irqsave(>tstamp_lock, flags); - timecounter_init(>tstamp_tc, nsec); + timecounter_reset(>tstamp_tc, nsec); spin_unlock_irqrestore(>tstamp_lock, flags); -- 1.9.1
[PATCH 27/27] timecounter: Remove timecounter_init
With all timecounter users now initializing timecounter using timecounter_initialize remove timecounter_init function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: John Stultz Cc: Thomas Gleixner Cc: Stephen Boyd Cc: linux-kernel@vger.kernel.org --- include/linux/timecounter.h | 20 +++- kernel/time/timecounter.c | 16 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h index e0fd741..e3e1d1e 100644 --- a/include/linux/timecounter.h +++ b/include/linux/timecounter.h @@ -46,8 +46,7 @@ struct cyclecounter { /** * struct timecounter - layer above a %struct cyclecounter which counts nanoseconds * Contains the state needed by timecounter_read() to detect - * cycle counter wrap around. Initialize with timecounter_init() when - * underlying cyclecounter is initialized, with timecounter_initialize() to + * cycle counter wrap around. Initialize with timecounter_initialize() to * initialize cyclecounter and timecounter fields. Also used to convert * cycle counts into the corresponding nanosecond counts with * timecounter_cyc2time(). Users of this code are responsible for @@ -97,18 +96,6 @@ static inline void timecounter_adjtime(struct timecounter *tc, s64 delta) } /** - * timecounter_init - initialize a time counter - * @tc:Pointer to time counter which is to be initialized - * @start_tstamp: Arbitrary initial time stamp. - * - * After this call the current cycle register (roughly) corresponds to - * the initial time stamp. Every call to timecounter_read() increments - * the time stamp counter by the number of elapsed nanoseconds. - */ -extern void timecounter_init(struct timecounter *tc, -u64 start_tstamp); - -/** * timecounter_initialize - initialize a time counter and underlying cyclecounter * @tc:Pointer to time counter which is to be initialized @@ -143,9 +130,8 @@ extern void timecounter_reset(struct timecounter *tc, u64 start_tstamp); /** - * timecounter_read - return nanoseconds elapsed since timecounter_init() or - *timecounter_initialize() or timecounter_reset() plus - * the initial time stamp + * timecounter_read - return nanoseconds elapsed since timecounter_initialize() + * or timecounter_reset() plus the initial time stamp * @tc: Pointer to time counter. * * In other words, keeps track of time since the same epoch as diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c index 3f62fe0..0a02ef0 100644 --- a/kernel/time/timecounter.c +++ b/kernel/time/timecounter.c @@ -18,17 +18,6 @@ #include #include -void timecounter_init(struct timecounter *tc, u64 start_tstamp) -{ - struct cyclecounter *cc = >cc; - - tc->cycle_last = cc->read(cc); - tc->nsec = start_tstamp; - tc->mask = (1ULL << cc->shift) - 1; - tc->frac = 0; -} -EXPORT_SYMBOL_GPL(timecounter_init); - void timecounter_initialize(struct timecounter *tc, u64 (*read)(const struct cyclecounter *cc), u64 mask, @@ -43,7 +32,10 @@ void timecounter_initialize(struct timecounter *tc, cc->mult = mult; cc->shift = shift; - timecounter_init(tc, start_tstamp); + tc->cycle_last = cc->read(cc); + tc->nsec = start_tstamp; + tc->mask = (1ULL << cc->shift) - 1; + tc->frac = 0; } EXPORT_SYMBOL_GPL(timecounter_initialize); -- 1.9.1
[PATCH 19/27] net: fec: ptp: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update fec_ptp_settime with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Fugang Duan <fugang.d...@nxp.com> Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/freescale/fec_ptp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 1ba7216..d03ea0e 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -419,7 +419,6 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp, { struct fec_enet_private *fep = container_of(ptp, struct fec_enet_private, ptp_caps); - u64 ns; unsigned long flags; u32 counter; @@ -439,7 +438,7 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp, spin_lock_irqsave(>tmreg_lock, flags); writel(counter, fep->hwp + FEC_ATIME); - timecounter_init(>tc, ns); + timecounter_reset(>tc, ns); spin_unlock_irqrestore(>tmreg_lock, flags); mutex_unlock(>ptp_clk_mutex); return 0; -- 1.9.1
[PATCH 19/27] net: fec: ptp: Use timecounter_reset interface
With new interface timecounter_reset we can update the start time for timecounter. Update fec_ptp_settime with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Fugang Duan Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/freescale/fec_ptp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 1ba7216..d03ea0e 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -419,7 +419,6 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp, { struct fec_enet_private *fep = container_of(ptp, struct fec_enet_private, ptp_caps); - u64 ns; unsigned long flags; u32 counter; @@ -439,7 +438,7 @@ static int fec_ptp_settime(struct ptp_clock_info *ptp, spin_lock_irqsave(>tmreg_lock, flags); writel(counter, fep->hwp + FEC_ATIME); - timecounter_init(>tc, ns); + timecounter_reset(>tc, ns); spin_unlock_irqrestore(>tmreg_lock, flags); mutex_unlock(>ptp_clk_mutex); return 0; -- 1.9.1
[PATCH 13/27] qede: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update qede timecounter init with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Ariel Elior <ariel.el...@cavium.com> Cc: everest-linux...@cavium.com Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/qlogic/qede/qede_ptp.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c b/drivers/net/ethernet/qlogic/qede/qede_ptp.c index 95bb8a8..0d054dc 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c +++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c @@ -427,13 +427,12 @@ static int qede_ptp_init(struct qede_dev *edev, bool init_tc) * unload / load (e.g. MTU change) while it is running. */ if (init_tc) { - memset(>tc.cc, 0, sizeof(ptp->tc.cc)); - ptp->tc.cc.read = qede_ptp_read_cc; - ptp->tc.cc.mask = CYCLECOUNTER_MASK(64); - ptp->tc.cc.shift = 0; - ptp->tc.cc.mult = 1; - - timecounter_init(>tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(>tc, + qede_ptp_read_cc, + CYCLECOUNTER_MASK(64), + 1, + 0, + ktime_to_ns(ktime_get_real())); } return rc; -- 1.9.1
[PATCH 13/27] qede: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update qede timecounter init with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Ariel Elior Cc: everest-linux...@cavium.com Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/qlogic/qede/qede_ptp.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c b/drivers/net/ethernet/qlogic/qede/qede_ptp.c index 95bb8a8..0d054dc 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c +++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c @@ -427,13 +427,12 @@ static int qede_ptp_init(struct qede_dev *edev, bool init_tc) * unload / load (e.g. MTU change) while it is running. */ if (init_tc) { - memset(>tc.cc, 0, sizeof(ptp->tc.cc)); - ptp->tc.cc.read = qede_ptp_read_cc; - ptp->tc.cc.mask = CYCLECOUNTER_MASK(64); - ptp->tc.cc.shift = 0; - ptp->tc.cc.mult = 1; - - timecounter_init(>tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(>tc, + qede_ptp_read_cc, + CYCLECOUNTER_MASK(64), + 1, + 0, + ktime_to_ns(ktime_get_real())); } return rc; -- 1.9.1
[PATCH 10/27] ixgbe: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update ixgbe ptp timecounter init with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Jeff Kirsher <jeffrey.t.kirs...@intel.com> Cc: intel-wired-...@lists.osuosl.org Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 6 +++- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +-- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 45 +++ 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 5c391a0..67e8b5c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -739,6 +739,10 @@ struct ixgbe_adapter { unsigned long last_rx_timestamp; spinlock_t tmreg_lock; struct timecounter hw_tc; + u64 (*cc_read)(const struct cyclecounter *cc); + u64 cc_mask; + u32 cc_mult; + u32 cc_shift; u32 base_incval; u32 tx_hwtstamp_timeouts; u32 tx_hwtstamp_skipped; @@ -994,7 +998,7 @@ static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring, int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); -void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); +void ixgbe_ptp_start_timecounter(struct ixgbe_adapter *adapter); void ixgbe_ptp_reset(struct ixgbe_adapter *adapter); void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter); #ifdef CONFIG_PCI_IOV diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 62a1891..86a337b 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -7332,7 +7332,7 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter) adapter->last_rx_ptp_check = jiffies; if (test_bit(__IXGBE_PTP_RUNNING, >state)) - ixgbe_ptp_start_cyclecounter(adapter); + ixgbe_ptp_start_timecounter(adapter); switch (link_speed) { case IXGBE_LINK_SPEED_10GB_FULL: @@ -7400,7 +7400,7 @@ static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter *adapter) adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP; if (test_bit(__IXGBE_PTP_RUNNING, >state)) - ixgbe_ptp_start_cyclecounter(adapter); + ixgbe_ptp_start_timecounter(adapter); e_info(drv, "NIC Link is Down\n"); netif_carrier_off(netdev); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 6e9f2c0..073c1ef 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -1075,7 +1075,8 @@ static void ixgbe_ptp_link_speed_adjust(struct ixgbe_adapter *adapter, } /** - * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw + * ixgbe_ptp_start_timecounter - create the cycle counter from hw and + * initialize corresponding timecounter. * @adapter: pointer to the adapter structure * * This function should be called to set the proper values for the TIMINCA @@ -1084,10 +1085,9 @@ static void ixgbe_ptp_link_speed_adjust(struct ixgbe_adapter *adapter, * structure. It should be called whenever a new TIMINCA value is necessary, * such as during initialization or when the link speed changes. */ -void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) +void ixgbe_ptp_start_timecounter(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = >hw; - struct cyclecounter cc; unsigned long flags; u32 incval = 0; u32 tsauxc = 0; @@ -1104,9 +1104,9 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) * proper fix to this problem would require modification of the * timecounter delta calculations. */ - cc.mask = CLOCKSOURCE_MASK(64); - cc.mult = 1; - cc.shift = 0; + adapter->cc_mask = CLOCKSOURCE_MASK(64); + adapter->cc_mult = 1; + adapter->cc_shift = 0; switch (hw->mac.type) { case ixgbe_mac_X550EM_x: @@ -1118,13 +1118,13 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) */ fuse0 = IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)); if (!(fuse0 & IXGBE_FUSES0_300MHZ)) { - cc.mult = 3; - cc.shift = 2; + adapter->cc_mult = 3; + adapter->cc_shift = 2; } /* fallthroug
[PATCH 02/27] timecounter: Introduce timecounter_initialize to update timecounter and cyclecounter
With cyclecounter coupled with timecounter, we should move to use interface that initializes entire timecounter structure. This patch creates function timecounter_initialize that takes cyclecounter parameters and start time and initializes the timecounter and underlying cyclecounter. Function timecounter_init which requires initialized cyclecounter can be removed once all drivers are migrated to this new interface. Suggested-by: Richard Cochran <richardcoch...@gmail.com> Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Chris Wilson <ch...@chris-wilson.co.uk> Cc: John Stultz <john.stu...@linaro.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Stephen Boyd <sb...@codeaurora.org> Cc: linux-kernel@vger.kernel.org --- include/linux/timecounter.h | 41 - kernel/time/timecounter.c | 18 ++ 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h index 6daca06..59d3fd7 100644 --- a/include/linux/timecounter.h +++ b/include/linux/timecounter.h @@ -46,13 +46,14 @@ struct cyclecounter { /** * struct timecounter - layer above a %struct cyclecounter which counts nanoseconds * Contains the state needed by timecounter_read() to detect - * cycle counter wrap around. Initialize with - * timecounter_init(). Also used to convert cycle counts into the - * corresponding nanosecond counts with timecounter_cyc2time(). Users - * of this code are responsible for initializing the underlying - * cycle counter hardware, locking issues and reading the time - * more often than the cycle counter wraps around. The nanosecond - * counter will only wrap around after ~585 years. + * cycle counter wrap around. Initialize with timecounter_init() when + * underlying cyclecounter is initialized, with timecounter_initialize() to + * initialize cyclecounter and timecounter fields. Also used to convert + * cycle counts into the corresponding nanosecond counts with + * timecounter_cyc2time(). Users of this code are responsible for + * locking issues and reading the time more often than the cycle counter + * wraps around. The nanosecond counter will only wrap around after ~585 + * years. * * @cc:the cycle counter used by this instance * @cycle_last:most recent cycle counter value seen by @@ -108,8 +109,30 @@ extern void timecounter_init(struct timecounter *tc, u64 start_tstamp); /** - * timecounter_read - return nanoseconds elapsed since timecounter_init() - *plus the initial time stamp + * timecounter_initialize - initialize a time counter and underlying + cyclecounter + * @tc:Pointer to time counter which is to be initialized + * @read: Pointer to function that returns the current cycle value + * @mask: bitmask for two's complement + * subtraction of non 64 bit counters, + * @mult: cycle to nanosecond multiplier + * @shift: cycle to nanosecond divisor (power of two) + * @start_tstamp: Arbitrary initial time stamp. + * + * After this call the current cycle register (roughly) corresponds to + * the initial time stamp. Every call to timecounter_read() increments + * the time stamp counter by the number of elapsed nanoseconds. + */ +extern void timecounter_initialize(struct timecounter *tc, + u64 (*read)(const struct cyclecounter *cc), + u64 mask, + u32 mult, + u32 shift, + u64 start_tstamp); + +/** + * timecounter_read - return nanoseconds elapsed since timecounter_init() or + *timecounter_initialize() plus the initial time stamp * @tc: Pointer to time counter. * * In other words, keeps track of time since the same epoch as diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c index 7919acb..6d915752 100644 --- a/kernel/time/timecounter.c +++ b/kernel/time/timecounter.c @@ -29,6 +29,24 @@ void timecounter_init(struct timecounter *tc, u64 start_tstamp) } EXPORT_SYMBOL_GPL(timecounter_init); +void timecounter_initialize(struct timecounter *tc, + u64 (*read)(const struct cyclecounter *cc), + u64 mask, + u32 mult, + u32 shift, + u64 start_tstamp) +{ + struct cyclecounter *cc = >cc; + + cc->read = read; + cc->mask = mask; + cc->mult = mult; + cc->shift = shift; + + timecounter_init(tc, start_tstamp); +} +EXPORT_SYMBOL_GPL(timecounter_initialize);
[PATCH 10/27] ixgbe: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update ixgbe ptp timecounter init with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Jeff Kirsher Cc: intel-wired-...@lists.osuosl.org Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 6 +++- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +-- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 45 +++ 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 5c391a0..67e8b5c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -739,6 +739,10 @@ struct ixgbe_adapter { unsigned long last_rx_timestamp; spinlock_t tmreg_lock; struct timecounter hw_tc; + u64 (*cc_read)(const struct cyclecounter *cc); + u64 cc_mask; + u32 cc_mult; + u32 cc_shift; u32 base_incval; u32 tx_hwtstamp_timeouts; u32 tx_hwtstamp_skipped; @@ -994,7 +998,7 @@ static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring, int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); -void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); +void ixgbe_ptp_start_timecounter(struct ixgbe_adapter *adapter); void ixgbe_ptp_reset(struct ixgbe_adapter *adapter); void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter); #ifdef CONFIG_PCI_IOV diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 62a1891..86a337b 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -7332,7 +7332,7 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter) adapter->last_rx_ptp_check = jiffies; if (test_bit(__IXGBE_PTP_RUNNING, >state)) - ixgbe_ptp_start_cyclecounter(adapter); + ixgbe_ptp_start_timecounter(adapter); switch (link_speed) { case IXGBE_LINK_SPEED_10GB_FULL: @@ -7400,7 +7400,7 @@ static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter *adapter) adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP; if (test_bit(__IXGBE_PTP_RUNNING, >state)) - ixgbe_ptp_start_cyclecounter(adapter); + ixgbe_ptp_start_timecounter(adapter); e_info(drv, "NIC Link is Down\n"); netif_carrier_off(netdev); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 6e9f2c0..073c1ef 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -1075,7 +1075,8 @@ static void ixgbe_ptp_link_speed_adjust(struct ixgbe_adapter *adapter, } /** - * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw + * ixgbe_ptp_start_timecounter - create the cycle counter from hw and + * initialize corresponding timecounter. * @adapter: pointer to the adapter structure * * This function should be called to set the proper values for the TIMINCA @@ -1084,10 +1085,9 @@ static void ixgbe_ptp_link_speed_adjust(struct ixgbe_adapter *adapter, * structure. It should be called whenever a new TIMINCA value is necessary, * such as during initialization or when the link speed changes. */ -void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) +void ixgbe_ptp_start_timecounter(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = >hw; - struct cyclecounter cc; unsigned long flags; u32 incval = 0; u32 tsauxc = 0; @@ -1104,9 +1104,9 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) * proper fix to this problem would require modification of the * timecounter delta calculations. */ - cc.mask = CLOCKSOURCE_MASK(64); - cc.mult = 1; - cc.shift = 0; + adapter->cc_mask = CLOCKSOURCE_MASK(64); + adapter->cc_mult = 1; + adapter->cc_shift = 0; switch (hw->mac.type) { case ixgbe_mac_X550EM_x: @@ -1118,13 +1118,13 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) */ fuse0 = IXGBE_READ_REG(hw, IXGBE_FUSES0_GROUP(0)); if (!(fuse0 & IXGBE_FUSES0_300MHZ)) { - cc.mult = 3; - cc.shift = 2; + adapter->cc_mult = 3; + adapter->cc_shift = 2; } /* fallthrough */ case ixgbe_mac_x550em_a: case ixgbe_mac_X550: - cc.read = ixgbe_
[PATCH 02/27] timecounter: Introduce timecounter_initialize to update timecounter and cyclecounter
With cyclecounter coupled with timecounter, we should move to use interface that initializes entire timecounter structure. This patch creates function timecounter_initialize that takes cyclecounter parameters and start time and initializes the timecounter and underlying cyclecounter. Function timecounter_init which requires initialized cyclecounter can be removed once all drivers are migrated to this new interface. Suggested-by: Richard Cochran Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Chris Wilson Cc: John Stultz Cc: Thomas Gleixner Cc: Stephen Boyd Cc: linux-kernel@vger.kernel.org --- include/linux/timecounter.h | 41 - kernel/time/timecounter.c | 18 ++ 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h index 6daca06..59d3fd7 100644 --- a/include/linux/timecounter.h +++ b/include/linux/timecounter.h @@ -46,13 +46,14 @@ struct cyclecounter { /** * struct timecounter - layer above a %struct cyclecounter which counts nanoseconds * Contains the state needed by timecounter_read() to detect - * cycle counter wrap around. Initialize with - * timecounter_init(). Also used to convert cycle counts into the - * corresponding nanosecond counts with timecounter_cyc2time(). Users - * of this code are responsible for initializing the underlying - * cycle counter hardware, locking issues and reading the time - * more often than the cycle counter wraps around. The nanosecond - * counter will only wrap around after ~585 years. + * cycle counter wrap around. Initialize with timecounter_init() when + * underlying cyclecounter is initialized, with timecounter_initialize() to + * initialize cyclecounter and timecounter fields. Also used to convert + * cycle counts into the corresponding nanosecond counts with + * timecounter_cyc2time(). Users of this code are responsible for + * locking issues and reading the time more often than the cycle counter + * wraps around. The nanosecond counter will only wrap around after ~585 + * years. * * @cc:the cycle counter used by this instance * @cycle_last:most recent cycle counter value seen by @@ -108,8 +109,30 @@ extern void timecounter_init(struct timecounter *tc, u64 start_tstamp); /** - * timecounter_read - return nanoseconds elapsed since timecounter_init() - *plus the initial time stamp + * timecounter_initialize - initialize a time counter and underlying + cyclecounter + * @tc:Pointer to time counter which is to be initialized + * @read: Pointer to function that returns the current cycle value + * @mask: bitmask for two's complement + * subtraction of non 64 bit counters, + * @mult: cycle to nanosecond multiplier + * @shift: cycle to nanosecond divisor (power of two) + * @start_tstamp: Arbitrary initial time stamp. + * + * After this call the current cycle register (roughly) corresponds to + * the initial time stamp. Every call to timecounter_read() increments + * the time stamp counter by the number of elapsed nanoseconds. + */ +extern void timecounter_initialize(struct timecounter *tc, + u64 (*read)(const struct cyclecounter *cc), + u64 mask, + u32 mult, + u32 shift, + u64 start_tstamp); + +/** + * timecounter_read - return nanoseconds elapsed since timecounter_init() or + *timecounter_initialize() plus the initial time stamp * @tc: Pointer to time counter. * * In other words, keeps track of time since the same epoch as diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c index 7919acb..6d915752 100644 --- a/kernel/time/timecounter.c +++ b/kernel/time/timecounter.c @@ -29,6 +29,24 @@ void timecounter_init(struct timecounter *tc, u64 start_tstamp) } EXPORT_SYMBOL_GPL(timecounter_init); +void timecounter_initialize(struct timecounter *tc, + u64 (*read)(const struct cyclecounter *cc), + u64 mask, + u32 mult, + u32 shift, + u64 start_tstamp) +{ + struct cyclecounter *cc = >cc; + + cc->read = read; + cc->mask = mask; + cc->mult = mult; + cc->shift = shift; + + timecounter_init(tc, start_tstamp); +} +EXPORT_SYMBOL_GPL(timecounter_initialize); + /** * timecounter_read_delta - get nanoseconds since last call of this function * @tc: Pointer to time counter -- 1.9.1
[PATCH 09/27] igb: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update igb ptp timecounter init with this new function. Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: Jeff Kirsher <jeffrey.t.kirs...@intel.com> Cc: intel-wired-...@lists.osuosl.org Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/intel/igb/igb.h | 4 drivers/net/ethernet/intel/igb/igb_ptp.c | 23 ++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index 4eac4f2..4ef5632 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h @@ -566,6 +566,10 @@ struct igb_adapter { unsigned int ptp_flags; spinlock_t tmreg_lock; struct timecounter tc; + u64 (*cc_read)(const struct cyclecounter *cc); + u64 cc_mask; + u32 cc_mult; + u32 cc_shift; u32 tx_hwtstamp_timeouts; u32 tx_hwtstamp_skipped; u32 rx_hwtstamp_cleared; diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index 0745eff..f6c1a8d 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -1126,10 +1126,10 @@ void igb_ptp_init(struct igb_adapter *adapter) adapter->ptp_caps.gettime64 = igb_ptp_gettime_82576; adapter->ptp_caps.settime64 = igb_ptp_settime_82576; adapter->ptp_caps.enable = igb_ptp_feature_enable; - adapter->tc.cc.read = igb_ptp_read_82576; - adapter->tc.cc.mask = CYCLECOUNTER_MASK(64); - adapter->tc.cc.mult = 1; - adapter->tc.cc.shift = IGB_82576_TSYNC_SHIFT; + adapter->cc_read = igb_ptp_read_82576; + adapter->cc_mask = CYCLECOUNTER_MASK(64); + adapter->cc_mult = 1; + adapter->cc_shift = IGB_82576_TSYNC_SHIFT; adapter->ptp_flags |= IGB_PTP_OVERFLOW_CHECK; break; case e1000_82580: @@ -1145,10 +1145,10 @@ void igb_ptp_init(struct igb_adapter *adapter) adapter->ptp_caps.gettime64 = igb_ptp_gettime_82576; adapter->ptp_caps.settime64 = igb_ptp_settime_82576; adapter->ptp_caps.enable = igb_ptp_feature_enable; - adapter->tc.cc.read = igb_ptp_read_82580; - adapter->tc.cc.mask = CYCLECOUNTER_MASK(IGB_NBITS_82580); - adapter->tc.cc.mult = 1; - adapter->tc.cc.shift = 0; + adapter->cc_read = igb_ptp_read_82580; + adapter->cc_mask = CYCLECOUNTER_MASK(IGB_NBITS_82580); + adapter->cc_mult = 1; + adapter->cc_shift = 0; adapter->ptp_flags |= IGB_PTP_OVERFLOW_CHECK; break; case e1000_i210: @@ -1289,7 +1289,12 @@ void igb_ptp_reset(struct igb_adapter *adapter) igb_ptp_write_i210(adapter, ); } else { - timecounter_init(>tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(>tc, + adapter->cc_read, + adapter->cc_mask, + adapter->cc_mult, + adapter->cc_shift, + ktime_to_ns(ktime_get_real())); } out: spin_unlock_irqrestore(>tmreg_lock, flags); -- 1.9.1
[PATCH 01/27] timecounter: Make cyclecounter struct part of timecounter struct
There is no real need for the users of timecounters to define cyclecounter and timecounter variables separately. Since timecounter will always be based on cyclecounter, have cyclecounter struct as member of timecounter struct. v2: Rebase. Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk> Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Chris Wilson <ch...@chris-wilson.co.uk> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: John Stultz <john.stu...@linaro.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Stephen Boyd <sb...@codeaurora.org> Cc: linux-kernel@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Cc: net...@vger.kernel.org Cc: intel-wired-...@lists.osuosl.org Cc: linux-r...@vger.kernel.org Cc: alsa-de...@alsa-project.org Cc: kvm...@lists.cs.columbia.edu Acked-by: Jeff Kirsher <jeffrey.t.kirs...@intel.com> (Intel drivers) --- arch/microblaze/kernel/timer.c | 20 ++-- drivers/clocksource/arm_arch_timer.c | 19 ++-- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 9 +++--- drivers/net/ethernet/amd/xgbe/xgbe.h | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x.h| 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 20 ++-- drivers/net/ethernet/freescale/fec.h | 1 - drivers/net/ethernet/freescale/fec_ptp.c | 30 +- drivers/net/ethernet/intel/e1000e/e1000.h | 1 - drivers/net/ethernet/intel/e1000e/netdev.c | 27 drivers/net/ethernet/intel/e1000e/ptp.c| 2 +- drivers/net/ethernet/intel/igb/igb.h | 1 - drivers/net/ethernet/intel/igb/igb_ptp.c | 25 --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 - drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 17 +- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 28 - drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 34 ++-- drivers/net/ethernet/qlogic/qede/qede_ptp.c| 20 ++-- drivers/net/ethernet/ti/cpts.c | 36 -- drivers/net/ethernet/ti/cpts.h | 1 - include/linux/mlx5/driver.h| 1 - include/linux/timecounter.h| 4 +-- include/sound/hdaudio.h| 1 - kernel/time/timecounter.c | 28 - sound/hda/hdac_stream.c| 7 +++-- virt/kvm/arm/arch_timer.c | 6 ++-- 28 files changed, 163 insertions(+), 182 deletions(-) diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 7de941c..b7f89e9 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -199,27 +199,25 @@ static u64 xilinx_read(struct clocksource *cs) return (u64)xilinx_clock_read(); } -static struct timecounter xilinx_tc = { - .cc = NULL, -}; - static u64 xilinx_cc_read(const struct cyclecounter *cc) { return xilinx_read(NULL); } -static struct cyclecounter xilinx_cc = { - .read = xilinx_cc_read, - .mask = CLOCKSOURCE_MASK(32), - .shift = 8, +static struct timecounter xilinx_tc = { + .cc.read = xilinx_cc_read, + .cc.mask = CLOCKSOURCE_MASK(32), + .cc.mult = 0, + .cc.shift = 8, }; static int __init init_xilinx_timecounter(void) { - xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC, - xilinx_cc.shift); + struct cyclecounter *cc = _tc.cc; + + cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift); - timecounter_init(_tc, _cc, sched_clock()); + timecounter_init(_tc, sched_clock()); return 0; } diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 57cb2f0..31543e5 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -179,11 +179,6 @@ static u64 arch_counter_read_cc(const struct cyclecounter *cc) .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static struct cyclecounter cyclecounter __ro_after_init = { - .read = arch_counter_read_cc, - .mask = CLOCKSOURCE_MASK(56), -}; - struct ate_acpi_oem_info { char oem_id[ACPI_OEM_ID_SIZE + 1]; char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; @@ -915,7 +910,10 @@ static u64 arch_counter_get_cntvct_mem(void) return ((u64) vct_hi << 32) | vct_lo; } -static struct arch_timer_kvm_info arch_timer_kvm_info; +static struct arch_timer_kvm_info arch_timer_kvm_info = { + .timecounter.cc.read = arch_counter_read_cc, + .timecounter.cc.mask = CLOCKSOURCE_MASK(56), +}; struct arch_timer_kvm_info
[PATCH 01/27] timecounter: Make cyclecounter struct part of timecounter struct
There is no real need for the users of timecounters to define cyclecounter and timecounter variables separately. Since timecounter will always be based on cyclecounter, have cyclecounter struct as member of timecounter struct. v2: Rebase. Suggested-by: Chris Wilson Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Richard Cochran Cc: John Stultz Cc: Thomas Gleixner Cc: Stephen Boyd Cc: linux-kernel@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Cc: net...@vger.kernel.org Cc: intel-wired-...@lists.osuosl.org Cc: linux-r...@vger.kernel.org Cc: alsa-de...@alsa-project.org Cc: kvm...@lists.cs.columbia.edu Acked-by: Jeff Kirsher (Intel drivers) --- arch/microblaze/kernel/timer.c | 20 ++-- drivers/clocksource/arm_arch_timer.c | 19 ++-- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 9 +++--- drivers/net/ethernet/amd/xgbe/xgbe.h | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x.h| 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 20 ++-- drivers/net/ethernet/freescale/fec.h | 1 - drivers/net/ethernet/freescale/fec_ptp.c | 30 +- drivers/net/ethernet/intel/e1000e/e1000.h | 1 - drivers/net/ethernet/intel/e1000e/netdev.c | 27 drivers/net/ethernet/intel/e1000e/ptp.c| 2 +- drivers/net/ethernet/intel/igb/igb.h | 1 - drivers/net/ethernet/intel/igb/igb_ptp.c | 25 --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 - drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 17 +- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 28 - drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 34 ++-- drivers/net/ethernet/qlogic/qede/qede_ptp.c| 20 ++-- drivers/net/ethernet/ti/cpts.c | 36 -- drivers/net/ethernet/ti/cpts.h | 1 - include/linux/mlx5/driver.h| 1 - include/linux/timecounter.h| 4 +-- include/sound/hdaudio.h| 1 - kernel/time/timecounter.c | 28 - sound/hda/hdac_stream.c| 7 +++-- virt/kvm/arm/arch_timer.c | 6 ++-- 28 files changed, 163 insertions(+), 182 deletions(-) diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 7de941c..b7f89e9 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -199,27 +199,25 @@ static u64 xilinx_read(struct clocksource *cs) return (u64)xilinx_clock_read(); } -static struct timecounter xilinx_tc = { - .cc = NULL, -}; - static u64 xilinx_cc_read(const struct cyclecounter *cc) { return xilinx_read(NULL); } -static struct cyclecounter xilinx_cc = { - .read = xilinx_cc_read, - .mask = CLOCKSOURCE_MASK(32), - .shift = 8, +static struct timecounter xilinx_tc = { + .cc.read = xilinx_cc_read, + .cc.mask = CLOCKSOURCE_MASK(32), + .cc.mult = 0, + .cc.shift = 8, }; static int __init init_xilinx_timecounter(void) { - xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC, - xilinx_cc.shift); + struct cyclecounter *cc = _tc.cc; + + cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift); - timecounter_init(_tc, _cc, sched_clock()); + timecounter_init(_tc, sched_clock()); return 0; } diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 57cb2f0..31543e5 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -179,11 +179,6 @@ static u64 arch_counter_read_cc(const struct cyclecounter *cc) .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static struct cyclecounter cyclecounter __ro_after_init = { - .read = arch_counter_read_cc, - .mask = CLOCKSOURCE_MASK(56), -}; - struct ate_acpi_oem_info { char oem_id[ACPI_OEM_ID_SIZE + 1]; char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; @@ -915,7 +910,10 @@ static u64 arch_counter_get_cntvct_mem(void) return ((u64) vct_hi << 32) | vct_lo; } -static struct arch_timer_kvm_info arch_timer_kvm_info; +static struct arch_timer_kvm_info arch_timer_kvm_info = { + .timecounter.cc.read = arch_counter_read_cc, + .timecounter.cc.mask = CLOCKSOURCE_MASK(56), +}; struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) { @@ -925,6 +923,7 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) static void __init arch_counter_register(unsigned type) { u64 start_count; + struct cyclecounter *cc = _timer_kvm_info.ti
[PATCH 09/27] igb: Use timecounter_initialize interface
With new interface timecounter_initialize we can initialize timecounter fields and underlying cyclecounter together. Update igb ptp timecounter init with this new function. Signed-off-by: Sagar Arun Kamble Cc: Richard Cochran Cc: Jeff Kirsher Cc: intel-wired-...@lists.osuosl.org Cc: net...@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- drivers/net/ethernet/intel/igb/igb.h | 4 drivers/net/ethernet/intel/igb/igb_ptp.c | 23 ++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index 4eac4f2..4ef5632 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h @@ -566,6 +566,10 @@ struct igb_adapter { unsigned int ptp_flags; spinlock_t tmreg_lock; struct timecounter tc; + u64 (*cc_read)(const struct cyclecounter *cc); + u64 cc_mask; + u32 cc_mult; + u32 cc_shift; u32 tx_hwtstamp_timeouts; u32 tx_hwtstamp_skipped; u32 rx_hwtstamp_cleared; diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index 0745eff..f6c1a8d 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -1126,10 +1126,10 @@ void igb_ptp_init(struct igb_adapter *adapter) adapter->ptp_caps.gettime64 = igb_ptp_gettime_82576; adapter->ptp_caps.settime64 = igb_ptp_settime_82576; adapter->ptp_caps.enable = igb_ptp_feature_enable; - adapter->tc.cc.read = igb_ptp_read_82576; - adapter->tc.cc.mask = CYCLECOUNTER_MASK(64); - adapter->tc.cc.mult = 1; - adapter->tc.cc.shift = IGB_82576_TSYNC_SHIFT; + adapter->cc_read = igb_ptp_read_82576; + adapter->cc_mask = CYCLECOUNTER_MASK(64); + adapter->cc_mult = 1; + adapter->cc_shift = IGB_82576_TSYNC_SHIFT; adapter->ptp_flags |= IGB_PTP_OVERFLOW_CHECK; break; case e1000_82580: @@ -1145,10 +1145,10 @@ void igb_ptp_init(struct igb_adapter *adapter) adapter->ptp_caps.gettime64 = igb_ptp_gettime_82576; adapter->ptp_caps.settime64 = igb_ptp_settime_82576; adapter->ptp_caps.enable = igb_ptp_feature_enable; - adapter->tc.cc.read = igb_ptp_read_82580; - adapter->tc.cc.mask = CYCLECOUNTER_MASK(IGB_NBITS_82580); - adapter->tc.cc.mult = 1; - adapter->tc.cc.shift = 0; + adapter->cc_read = igb_ptp_read_82580; + adapter->cc_mask = CYCLECOUNTER_MASK(IGB_NBITS_82580); + adapter->cc_mult = 1; + adapter->cc_shift = 0; adapter->ptp_flags |= IGB_PTP_OVERFLOW_CHECK; break; case e1000_i210: @@ -1289,7 +1289,12 @@ void igb_ptp_reset(struct igb_adapter *adapter) igb_ptp_write_i210(adapter, ); } else { - timecounter_init(>tc, ktime_to_ns(ktime_get_real())); + timecounter_initialize(>tc, + adapter->cc_read, + adapter->cc_mask, + adapter->cc_mult, + adapter->cc_shift, + ktime_to_ns(ktime_get_real())); } out: spin_unlock_irqrestore(>tmreg_lock, flags); -- 1.9.1
[PATCH 00/27] timecounter/cyclecounter struct/interface update
This series makes cyclecounter part of timecounter and introduces two new interface functions timecounter_initialize() for initializing both timecounter and cyclecounter fields and timecounter_reset() for setting start time of timecounter. Updates all drivers with new functions and removes function timecounter_init(). Cc: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: John Stultz <john.stu...@linaro.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Stephen Boyd <sb...@codeaurora.org> Cc: linux-kernel@vger.kernel.org Sagar Arun Kamble (27): timecounter: Make cyclecounter struct part of timecounter struct timecounter: Introduce timecounter_initialize to update timecounter and cyclecounter microblaze: Use timecounter_initialize interface clocksource/arm_arch_timer: Use timecounter_initialize interface amd-xgbe: Use timecounter_initialize interface bnx2x: Use timecounter_initialize interface fec: Use timecounter_initialize interface e1000e: Use timecounter_initialize interface igb: Use timecounter_initialize interface ixgbe: Use timecounter_initialize interface net/mlx4: Use timecounter_initialize interface net/mlx5: Use timecounter_initialize interface qede: Use timecounter_initialize interface net: cpts: Use timecounter_initialize interface ALSA: hda - Use timecounter_initialize interface timecounter: Introduce timecounter_reset amd-xgbe: Use timecounter_reset interface bnx2x: Use timecounter_reset interface net: fec: ptp: Use timecounter_reset interface e1000e: Use timecounter_reset interface igb: Use timecounter_reset interface ixgbe: Use timecounter_reset interface net/mlx4: Use timecounter_reset interface net/mlx5: Use timecounter_reset interface qede: Use timecounter_reset interface net: cpts: Use timecounter_reset interface timecounter: Remove timecounter_init arch/microblaze/kernel/timer.c | 23 - drivers/clocksource/arm_arch_timer.c | 16 +++--- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 5 +- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 18 +++ drivers/net/ethernet/amd/xgbe/xgbe.h | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x.h| 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 24 - drivers/net/ethernet/freescale/fec.h | 1 - drivers/net/ethernet/freescale/fec_ptp.c | 34 ++--- drivers/net/ethernet/intel/e1000e/e1000.h | 5 +- drivers/net/ethernet/intel/e1000e/netdev.c | 34 +++-- drivers/net/ethernet/intel/e1000e/ptp.c| 2 +- drivers/net/ethernet/intel/igb/igb.h | 5 +- drivers/net/ethernet/intel/igb/igb_ptp.c | 30 ++- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 7 ++- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 58 -- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 29 +-- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 38 +++--- drivers/net/ethernet/qlogic/qede/qede_ptp.c| 21 drivers/net/ethernet/ti/cpts.c | 45 ++--- drivers/net/ethernet/ti/cpts.h | 4 +- include/linux/mlx5/driver.h| 1 - include/linux/timecounter.h| 52 +-- include/sound/hdaudio.h| 1 - kernel/time/timecounter.c | 49 -- sound/hda/hdac_stream.c| 17 +++ virt/kvm/arm/arch_timer.c | 6 +-- 29 files changed, 291 insertions(+), 241 deletions(-) -- 1.9.1
[PATCH 00/27] timecounter/cyclecounter struct/interface update
This series makes cyclecounter part of timecounter and introduces two new interface functions timecounter_initialize() for initializing both timecounter and cyclecounter fields and timecounter_reset() for setting start time of timecounter. Updates all drivers with new functions and removes function timecounter_init(). Cc: Sagar Arun Kamble Cc: Richard Cochran Cc: John Stultz Cc: Thomas Gleixner Cc: Stephen Boyd Cc: linux-kernel@vger.kernel.org Sagar Arun Kamble (27): timecounter: Make cyclecounter struct part of timecounter struct timecounter: Introduce timecounter_initialize to update timecounter and cyclecounter microblaze: Use timecounter_initialize interface clocksource/arm_arch_timer: Use timecounter_initialize interface amd-xgbe: Use timecounter_initialize interface bnx2x: Use timecounter_initialize interface fec: Use timecounter_initialize interface e1000e: Use timecounter_initialize interface igb: Use timecounter_initialize interface ixgbe: Use timecounter_initialize interface net/mlx4: Use timecounter_initialize interface net/mlx5: Use timecounter_initialize interface qede: Use timecounter_initialize interface net: cpts: Use timecounter_initialize interface ALSA: hda - Use timecounter_initialize interface timecounter: Introduce timecounter_reset amd-xgbe: Use timecounter_reset interface bnx2x: Use timecounter_reset interface net: fec: ptp: Use timecounter_reset interface e1000e: Use timecounter_reset interface igb: Use timecounter_reset interface ixgbe: Use timecounter_reset interface net/mlx4: Use timecounter_reset interface net/mlx5: Use timecounter_reset interface qede: Use timecounter_reset interface net: cpts: Use timecounter_reset interface timecounter: Remove timecounter_init arch/microblaze/kernel/timer.c | 23 - drivers/clocksource/arm_arch_timer.c | 16 +++--- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 5 +- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 18 +++ drivers/net/ethernet/amd/xgbe/xgbe.h | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x.h| 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 24 - drivers/net/ethernet/freescale/fec.h | 1 - drivers/net/ethernet/freescale/fec_ptp.c | 34 ++--- drivers/net/ethernet/intel/e1000e/e1000.h | 5 +- drivers/net/ethernet/intel/e1000e/netdev.c | 34 +++-- drivers/net/ethernet/intel/e1000e/ptp.c| 2 +- drivers/net/ethernet/intel/igb/igb.h | 5 +- drivers/net/ethernet/intel/igb/igb_ptp.c | 30 ++- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 7 ++- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 58 -- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 29 +-- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 38 +++--- drivers/net/ethernet/qlogic/qede/qede_ptp.c| 21 drivers/net/ethernet/ti/cpts.c | 45 ++--- drivers/net/ethernet/ti/cpts.h | 4 +- include/linux/mlx5/driver.h| 1 - include/linux/timecounter.h| 52 +-- include/sound/hdaudio.h| 1 - kernel/time/timecounter.c | 49 -- sound/hda/hdac_stream.c| 17 +++ virt/kvm/arm/arch_timer.c | 6 +-- 29 files changed, 291 insertions(+), 241 deletions(-) -- 1.9.1
Re: [PATCH 1/1] timecounter: Make cyclecounter struct part of timecounter struct
On 12/2/2017 11:34 PM, Richard Cochran wrote: On Sat, Dec 02, 2017 at 10:01:35AM +0530, Sagar Arun Kamble wrote: There is no real need for the users of timecounters to define cyclecounter and timecounter variables separately. Since timecounter will always be based on cyclecounter, have cyclecounter struct as member of timecounter struct. Overall, this is a welcome change. However, it doesn't go far enough, IMHO, and I'll explain that more below. diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index 0247885..35987b5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c ... As it stands now, timecounter_init() is used for two totally different reasons. Some callers only want to set the time, ... @@ -207,7 +207,7 @@ static int mlx4_en_phc_settime(struct ptp_clock_info *ptp, /* reset the timecounter */ write_seqlock_irqsave(>clock_lock, flags); - timecounter_init(>clock, >cycles, ns); + timecounter_init(>clock, ns); write_sequnlock_irqrestore(>clock_lock, flags); return 0; ... while others initialize the data structure the first time: @@ -274,17 +274,17 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) seqlock_init(>clock_lock); - memset(>cycles, 0, sizeof(mdev->cycles)); - mdev->cycles.read = mlx4_en_read_clock; - mdev->cycles.mask = CLOCKSOURCE_MASK(48); - mdev->cycles.shift = freq_to_shift(dev->caps.hca_core_clock); - mdev->cycles.mult = - clocksource_khz2mult(1000 * dev->caps.hca_core_clock, mdev->cycles.shift); - mdev->nominal_c_mult = mdev->cycles.mult; + memset(>clock.cc, 0, sizeof(mdev->clock.cc)); + mdev->clock.cc.read = mlx4_en_read_clock; + mdev->clock.cc.mask = CLOCKSOURCE_MASK(48); + mdev->clock.cc.shift = freq_to_shift(dev->caps.hca_core_clock); + mdev->clock.cc.mult = + clocksource_khz2mult(1000 * dev->caps.hca_core_clock, +mdev->clock.cc.shift); + mdev->nominal_c_mult = mdev->clock.cc.mult; write_seqlock_irqsave(>clock_lock, flags); - timecounter_init(>clock, >cycles, -ktime_to_ns(ktime_get_real())); + timecounter_init(>clock, ktime_to_ns(ktime_get_real())); I'd like to see two followup patches to this one: 1. Convert timecounter_init() callers to a new timecounter_reset() function where the intent is to reset the time. 2. Change timecounter_init() to take the cyclecounter fields as arguments. void timecounter_init(struct timecounter *tc, u64 (*read)(const struct cyclecounter *cc), u64 mask, u32 mult, u32 shift, u64 start_tstamp); Then we can clean up all this stuff: mdev->clock.cc.read = mlx4_en_read_clock; mdev->clock.cc.mask = CLOCKSOURCE_MASK(48); mdev->clock.cc.shift = freq_to_shift(dev->caps.hca_core_clock); mdev->clock.cc.mult = clocksource_khz2mult(...); This second step can be phased in by calling the new function timecounter_initialize() and converting the drivers one by one. Yes. Will make these changes and share new patchset. Thank you for the review Richard. Regards, Sagar diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h index 2496ad4..6daca06 100644 --- a/include/linux/timecounter.h +++ b/include/linux/timecounter.h ... @@ -98,7 +98,6 @@ static inline void timecounter_adjtime(struct timecounter *tc, s64 delta) /** * timecounter_init - initialize a time counter * @tc: Pointer to time counter which is to be initialized/reset - * @cc:A cycle counter, ready to be used. This "ready to used" requirement should go. The init() function should make the instance ready to be used all at once. Thanks, Richard
Re: [PATCH 1/1] timecounter: Make cyclecounter struct part of timecounter struct
On 12/2/2017 11:34 PM, Richard Cochran wrote: On Sat, Dec 02, 2017 at 10:01:35AM +0530, Sagar Arun Kamble wrote: There is no real need for the users of timecounters to define cyclecounter and timecounter variables separately. Since timecounter will always be based on cyclecounter, have cyclecounter struct as member of timecounter struct. Overall, this is a welcome change. However, it doesn't go far enough, IMHO, and I'll explain that more below. diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index 0247885..35987b5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c ... As it stands now, timecounter_init() is used for two totally different reasons. Some callers only want to set the time, ... @@ -207,7 +207,7 @@ static int mlx4_en_phc_settime(struct ptp_clock_info *ptp, /* reset the timecounter */ write_seqlock_irqsave(>clock_lock, flags); - timecounter_init(>clock, >cycles, ns); + timecounter_init(>clock, ns); write_sequnlock_irqrestore(>clock_lock, flags); return 0; ... while others initialize the data structure the first time: @@ -274,17 +274,17 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) seqlock_init(>clock_lock); - memset(>cycles, 0, sizeof(mdev->cycles)); - mdev->cycles.read = mlx4_en_read_clock; - mdev->cycles.mask = CLOCKSOURCE_MASK(48); - mdev->cycles.shift = freq_to_shift(dev->caps.hca_core_clock); - mdev->cycles.mult = - clocksource_khz2mult(1000 * dev->caps.hca_core_clock, mdev->cycles.shift); - mdev->nominal_c_mult = mdev->cycles.mult; + memset(>clock.cc, 0, sizeof(mdev->clock.cc)); + mdev->clock.cc.read = mlx4_en_read_clock; + mdev->clock.cc.mask = CLOCKSOURCE_MASK(48); + mdev->clock.cc.shift = freq_to_shift(dev->caps.hca_core_clock); + mdev->clock.cc.mult = + clocksource_khz2mult(1000 * dev->caps.hca_core_clock, +mdev->clock.cc.shift); + mdev->nominal_c_mult = mdev->clock.cc.mult; write_seqlock_irqsave(>clock_lock, flags); - timecounter_init(>clock, >cycles, -ktime_to_ns(ktime_get_real())); + timecounter_init(>clock, ktime_to_ns(ktime_get_real())); I'd like to see two followup patches to this one: 1. Convert timecounter_init() callers to a new timecounter_reset() function where the intent is to reset the time. 2. Change timecounter_init() to take the cyclecounter fields as arguments. void timecounter_init(struct timecounter *tc, u64 (*read)(const struct cyclecounter *cc), u64 mask, u32 mult, u32 shift, u64 start_tstamp); Then we can clean up all this stuff: mdev->clock.cc.read = mlx4_en_read_clock; mdev->clock.cc.mask = CLOCKSOURCE_MASK(48); mdev->clock.cc.shift = freq_to_shift(dev->caps.hca_core_clock); mdev->clock.cc.mult = clocksource_khz2mult(...); This second step can be phased in by calling the new function timecounter_initialize() and converting the drivers one by one. Yes. Will make these changes and share new patchset. Thank you for the review Richard. Regards, Sagar diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h index 2496ad4..6daca06 100644 --- a/include/linux/timecounter.h +++ b/include/linux/timecounter.h ... @@ -98,7 +98,6 @@ static inline void timecounter_adjtime(struct timecounter *tc, s64 delta) /** * timecounter_init - initialize a time counter * @tc: Pointer to time counter which is to be initialized/reset - * @cc:A cycle counter, ready to be used. This "ready to used" requirement should go. The init() function should make the instance ready to be used all at once. Thanks, Richard
[PATCH 1/1] timecounter: Make cyclecounter struct part of timecounter struct
There is no real need for the users of timecounters to define cyclecounter and timecounter variables separately. Since timecounter will always be based on cyclecounter, have cyclecounter struct as member of timecounter struct. Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk> Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Chris Wilson <ch...@chris-wilson.co.uk> Cc: Richard Cochran <richardcoch...@gmail.com> Cc: John Stultz <john.stu...@linaro.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Stephen Boyd <sb...@codeaurora.org> Cc: linux-kernel@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Cc: net...@vger.kernel.org Cc: intel-wired-...@lists.osuosl.org Cc: linux-r...@vger.kernel.org Cc: alsa-de...@alsa-project.org Cc: kvm...@lists.cs.columbia.edu --- arch/microblaze/kernel/timer.c | 20 ++-- drivers/clocksource/arm_arch_timer.c | 19 ++-- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 9 +++--- drivers/net/ethernet/amd/xgbe/xgbe.h | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x.h| 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 20 ++-- drivers/net/ethernet/freescale/fec.h | 1 - drivers/net/ethernet/freescale/fec_ptp.c | 30 +- drivers/net/ethernet/intel/e1000e/e1000.h | 1 - drivers/net/ethernet/intel/e1000e/netdev.c | 27 drivers/net/ethernet/intel/e1000e/ptp.c| 2 +- drivers/net/ethernet/intel/igb/igb.h | 1 - drivers/net/ethernet/intel/igb/igb_ptp.c | 25 --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 - drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 17 +- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 28 - drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 34 ++-- drivers/net/ethernet/qlogic/qede/qede_ptp.c| 20 ++-- drivers/net/ethernet/ti/cpts.c | 36 -- drivers/net/ethernet/ti/cpts.h | 1 - include/linux/mlx5/driver.h| 1 - include/linux/timecounter.h| 4 +-- include/sound/hdaudio.h| 1 - kernel/time/timecounter.c | 28 - sound/hda/hdac_stream.c| 7 +++-- virt/kvm/arm/arch_timer.c | 6 ++-- 28 files changed, 163 insertions(+), 182 deletions(-) diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 7de941c..b7f89e9 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -199,27 +199,25 @@ static u64 xilinx_read(struct clocksource *cs) return (u64)xilinx_clock_read(); } -static struct timecounter xilinx_tc = { - .cc = NULL, -}; - static u64 xilinx_cc_read(const struct cyclecounter *cc) { return xilinx_read(NULL); } -static struct cyclecounter xilinx_cc = { - .read = xilinx_cc_read, - .mask = CLOCKSOURCE_MASK(32), - .shift = 8, +static struct timecounter xilinx_tc = { + .cc.read = xilinx_cc_read, + .cc.mask = CLOCKSOURCE_MASK(32), + .cc.mult = 0, + .cc.shift = 8, }; static int __init init_xilinx_timecounter(void) { - xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC, - xilinx_cc.shift); + struct cyclecounter *cc = _tc.cc; + + cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift); - timecounter_init(_tc, _cc, sched_clock()); + timecounter_init(_tc, sched_clock()); return 0; } diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 57cb2f0..31543e5 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -179,11 +179,6 @@ static u64 arch_counter_read_cc(const struct cyclecounter *cc) .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static struct cyclecounter cyclecounter __ro_after_init = { - .read = arch_counter_read_cc, - .mask = CLOCKSOURCE_MASK(56), -}; - struct ate_acpi_oem_info { char oem_id[ACPI_OEM_ID_SIZE + 1]; char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; @@ -915,7 +910,10 @@ static u64 arch_counter_get_cntvct_mem(void) return ((u64) vct_hi << 32) | vct_lo; } -static struct arch_timer_kvm_info arch_timer_kvm_info; +static struct arch_timer_kvm_info arch_timer_kvm_info = { + .timecounter.cc.read = arch_counter_read_cc, + .timecounter.cc.mask = CLOCKSOURCE_MASK(56), +}; struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) { @@ -925,6 +923,7 @@ struct arch_timer_kvm_info *arch_timer_get_kv
[PATCH 1/1] timecounter: Make cyclecounter struct part of timecounter struct
There is no real need for the users of timecounters to define cyclecounter and timecounter variables separately. Since timecounter will always be based on cyclecounter, have cyclecounter struct as member of timecounter struct. Suggested-by: Chris Wilson Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Richard Cochran Cc: John Stultz Cc: Thomas Gleixner Cc: Stephen Boyd Cc: linux-kernel@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Cc: net...@vger.kernel.org Cc: intel-wired-...@lists.osuosl.org Cc: linux-r...@vger.kernel.org Cc: alsa-de...@alsa-project.org Cc: kvm...@lists.cs.columbia.edu --- arch/microblaze/kernel/timer.c | 20 ++-- drivers/clocksource/arm_arch_timer.c | 19 ++-- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 9 +++--- drivers/net/ethernet/amd/xgbe/xgbe.h | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x.h| 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 20 ++-- drivers/net/ethernet/freescale/fec.h | 1 - drivers/net/ethernet/freescale/fec_ptp.c | 30 +- drivers/net/ethernet/intel/e1000e/e1000.h | 1 - drivers/net/ethernet/intel/e1000e/netdev.c | 27 drivers/net/ethernet/intel/e1000e/ptp.c| 2 +- drivers/net/ethernet/intel/igb/igb.h | 1 - drivers/net/ethernet/intel/igb/igb_ptp.c | 25 --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 - drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 17 +- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 28 - drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 34 ++-- drivers/net/ethernet/qlogic/qede/qede_ptp.c| 20 ++-- drivers/net/ethernet/ti/cpts.c | 36 -- drivers/net/ethernet/ti/cpts.h | 1 - include/linux/mlx5/driver.h| 1 - include/linux/timecounter.h| 4 +-- include/sound/hdaudio.h| 1 - kernel/time/timecounter.c | 28 - sound/hda/hdac_stream.c| 7 +++-- virt/kvm/arm/arch_timer.c | 6 ++-- 28 files changed, 163 insertions(+), 182 deletions(-) diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 7de941c..b7f89e9 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -199,27 +199,25 @@ static u64 xilinx_read(struct clocksource *cs) return (u64)xilinx_clock_read(); } -static struct timecounter xilinx_tc = { - .cc = NULL, -}; - static u64 xilinx_cc_read(const struct cyclecounter *cc) { return xilinx_read(NULL); } -static struct cyclecounter xilinx_cc = { - .read = xilinx_cc_read, - .mask = CLOCKSOURCE_MASK(32), - .shift = 8, +static struct timecounter xilinx_tc = { + .cc.read = xilinx_cc_read, + .cc.mask = CLOCKSOURCE_MASK(32), + .cc.mult = 0, + .cc.shift = 8, }; static int __init init_xilinx_timecounter(void) { - xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC, - xilinx_cc.shift); + struct cyclecounter *cc = _tc.cc; + + cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift); - timecounter_init(_tc, _cc, sched_clock()); + timecounter_init(_tc, sched_clock()); return 0; } diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 57cb2f0..31543e5 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -179,11 +179,6 @@ static u64 arch_counter_read_cc(const struct cyclecounter *cc) .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static struct cyclecounter cyclecounter __ro_after_init = { - .read = arch_counter_read_cc, - .mask = CLOCKSOURCE_MASK(56), -}; - struct ate_acpi_oem_info { char oem_id[ACPI_OEM_ID_SIZE + 1]; char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; @@ -915,7 +910,10 @@ static u64 arch_counter_get_cntvct_mem(void) return ((u64) vct_hi << 32) | vct_lo; } -static struct arch_timer_kvm_info arch_timer_kvm_info; +static struct arch_timer_kvm_info arch_timer_kvm_info = { + .timecounter.cc.read = arch_counter_read_cc, + .timecounter.cc.mask = CLOCKSOURCE_MASK(56), +}; struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) { @@ -925,6 +923,7 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) static void __init arch_counter_register(unsigned type) { u64 start_count; + struct cyclecounter *cc = _timer_kvm_info.timecounter.cc; /* Register the CP15 based counter if
[PATCH 1/1] timecounter: Make cyclecounter struct part of timecounter struct
There is no real need for the users of timecounters to define cyclecounter and timecounter variables separately. Since timecounter will always be based on cyclecounter, have cyclecounter struct as member of timecounter struct. Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk> Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: Chris Wilson <ch...@chris-wilson.co.uk> Cc: John Stultz <john.stu...@linaro.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Stephen Boyd <sb...@codeaurora.org> Cc: linux-kernel@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Cc: net...@vger.kernel.org Cc: intel-wired-...@lists.osuosl.org Cc: linux-r...@vger.kernel.org Cc: alsa-de...@alsa-project.org Cc: kvm...@lists.cs.columbia.edu --- arch/microblaze/kernel/timer.c | 20 ++-- drivers/clocksource/arm_arch_timer.c | 19 ++-- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 9 +++--- drivers/net/ethernet/amd/xgbe/xgbe.h | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x.h| 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 20 ++-- drivers/net/ethernet/freescale/fec.h | 1 - drivers/net/ethernet/freescale/fec_ptp.c | 30 +- drivers/net/ethernet/intel/e1000e/e1000.h | 1 - drivers/net/ethernet/intel/e1000e/netdev.c | 27 drivers/net/ethernet/intel/e1000e/ptp.c| 2 +- drivers/net/ethernet/intel/igb/igb.h | 1 - drivers/net/ethernet/intel/igb/igb_ptp.c | 25 --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 - drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 17 +- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 28 - drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 34 ++-- drivers/net/ethernet/qlogic/qede/qede_ptp.c| 20 ++-- drivers/net/ethernet/ti/cpts.c | 36 -- drivers/net/ethernet/ti/cpts.h | 1 - include/linux/mlx5/driver.h| 1 - include/linux/timecounter.h| 4 +-- include/sound/hdaudio.h| 1 - kernel/time/timecounter.c | 28 - sound/hda/hdac_stream.c| 7 +++-- virt/kvm/arm/arch_timer.c | 6 ++-- 28 files changed, 163 insertions(+), 182 deletions(-) diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 7de941c..b7f89e9 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -199,27 +199,25 @@ static u64 xilinx_read(struct clocksource *cs) return (u64)xilinx_clock_read(); } -static struct timecounter xilinx_tc = { - .cc = NULL, -}; - static u64 xilinx_cc_read(const struct cyclecounter *cc) { return xilinx_read(NULL); } -static struct cyclecounter xilinx_cc = { - .read = xilinx_cc_read, - .mask = CLOCKSOURCE_MASK(32), - .shift = 8, +static struct timecounter xilinx_tc = { + .cc.read = xilinx_cc_read, + .cc.mask = CLOCKSOURCE_MASK(32), + .cc.mult = 0, + .cc.shift = 8, }; static int __init init_xilinx_timecounter(void) { - xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC, - xilinx_cc.shift); + struct cyclecounter *cc = _tc.cc; + + cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift); - timecounter_init(_tc, _cc, sched_clock()); + timecounter_init(_tc, sched_clock()); return 0; } diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 57cb2f0..31543e5 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -179,11 +179,6 @@ static u64 arch_counter_read_cc(const struct cyclecounter *cc) .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static struct cyclecounter cyclecounter __ro_after_init = { - .read = arch_counter_read_cc, - .mask = CLOCKSOURCE_MASK(56), -}; - struct ate_acpi_oem_info { char oem_id[ACPI_OEM_ID_SIZE + 1]; char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; @@ -915,7 +910,10 @@ static u64 arch_counter_get_cntvct_mem(void) return ((u64) vct_hi << 32) | vct_lo; } -static struct arch_timer_kvm_info arch_timer_kvm_info; +static struct arch_timer_kvm_info arch_timer_kvm_info = { + .timecounter.cc.read = arch_counter_read_cc, + .timecounter.cc.mask = CLOCKSOURCE_MASK(56), +}; struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) { @@ -925,6 +923,7 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) static void __init arch_counter_re
[PATCH 1/1] timecounter: Make cyclecounter struct part of timecounter struct
There is no real need for the users of timecounters to define cyclecounter and timecounter variables separately. Since timecounter will always be based on cyclecounter, have cyclecounter struct as member of timecounter struct. Suggested-by: Chris Wilson Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: John Stultz Cc: Thomas Gleixner Cc: Stephen Boyd Cc: linux-kernel@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Cc: net...@vger.kernel.org Cc: intel-wired-...@lists.osuosl.org Cc: linux-r...@vger.kernel.org Cc: alsa-de...@alsa-project.org Cc: kvm...@lists.cs.columbia.edu --- arch/microblaze/kernel/timer.c | 20 ++-- drivers/clocksource/arm_arch_timer.c | 19 ++-- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 9 +++--- drivers/net/ethernet/amd/xgbe/xgbe.h | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x.h| 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 20 ++-- drivers/net/ethernet/freescale/fec.h | 1 - drivers/net/ethernet/freescale/fec_ptp.c | 30 +- drivers/net/ethernet/intel/e1000e/e1000.h | 1 - drivers/net/ethernet/intel/e1000e/netdev.c | 27 drivers/net/ethernet/intel/e1000e/ptp.c| 2 +- drivers/net/ethernet/intel/igb/igb.h | 1 - drivers/net/ethernet/intel/igb/igb_ptp.c | 25 --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 - drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 17 +- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 28 - drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - .../net/ethernet/mellanox/mlx5/core/lib/clock.c| 34 ++-- drivers/net/ethernet/qlogic/qede/qede_ptp.c| 20 ++-- drivers/net/ethernet/ti/cpts.c | 36 -- drivers/net/ethernet/ti/cpts.h | 1 - include/linux/mlx5/driver.h| 1 - include/linux/timecounter.h| 4 +-- include/sound/hdaudio.h| 1 - kernel/time/timecounter.c | 28 - sound/hda/hdac_stream.c| 7 +++-- virt/kvm/arm/arch_timer.c | 6 ++-- 28 files changed, 163 insertions(+), 182 deletions(-) diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 7de941c..b7f89e9 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -199,27 +199,25 @@ static u64 xilinx_read(struct clocksource *cs) return (u64)xilinx_clock_read(); } -static struct timecounter xilinx_tc = { - .cc = NULL, -}; - static u64 xilinx_cc_read(const struct cyclecounter *cc) { return xilinx_read(NULL); } -static struct cyclecounter xilinx_cc = { - .read = xilinx_cc_read, - .mask = CLOCKSOURCE_MASK(32), - .shift = 8, +static struct timecounter xilinx_tc = { + .cc.read = xilinx_cc_read, + .cc.mask = CLOCKSOURCE_MASK(32), + .cc.mult = 0, + .cc.shift = 8, }; static int __init init_xilinx_timecounter(void) { - xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC, - xilinx_cc.shift); + struct cyclecounter *cc = _tc.cc; + + cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift); - timecounter_init(_tc, _cc, sched_clock()); + timecounter_init(_tc, sched_clock()); return 0; } diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 57cb2f0..31543e5 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -179,11 +179,6 @@ static u64 arch_counter_read_cc(const struct cyclecounter *cc) .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static struct cyclecounter cyclecounter __ro_after_init = { - .read = arch_counter_read_cc, - .mask = CLOCKSOURCE_MASK(56), -}; - struct ate_acpi_oem_info { char oem_id[ACPI_OEM_ID_SIZE + 1]; char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; @@ -915,7 +910,10 @@ static u64 arch_counter_get_cntvct_mem(void) return ((u64) vct_hi << 32) | vct_lo; } -static struct arch_timer_kvm_info arch_timer_kvm_info; +static struct arch_timer_kvm_info arch_timer_kvm_info = { + .timecounter.cc.read = arch_counter_read_cc, + .timecounter.cc.mask = CLOCKSOURCE_MASK(56), +}; struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) { @@ -925,6 +923,7 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) static void __init arch_counter_register(unsigned type) { u64 start_count; + struct cyclecounter *cc = _timer_kvm_info.timecounter.cc; /* Register the CP15 based counter if we have one */
Re: Creating cyclecounter and lock member in timecounter structure [ Was Re: [RFC 1/4] drm/i915/perf: Add support to correlate GPU timestamp with system time]
On 12/1/2017 2:33 AM, Saeed Mahameed wrote: On Mon, Nov 27, 2017 at 2:05 AM, Sagar Arun Kamble <sagar.a.kam...@intel.com> wrote: On 11/24/2017 7:01 PM, Thomas Gleixner wrote: On Fri, 24 Nov 2017, Sagar Arun Kamble wrote: On 11/24/2017 12:29 AM, Thomas Gleixner wrote: On Thu, 23 Nov 2017, Sagar Arun Kamble wrote: We needed inputs on possible optimization that can be done to timecounter/cyclecounter structures/usage. This mail is in response to review of patch https://patchwork.freedesktop.org/patch/188448/. As Chris's observation below, about dozen of timecounter users in the kernel have below structures defined individually: spinlock_t lock; struct cyclecounter cc; struct timecounter tc; Can we move lock and cc to tc? That way it will be convenient. Also it will allow unifying the locking/overflow watchdog handling across all drivers. Looks like none of the timecounter usage sites has a real need to separate timecounter and cyclecounter. Yes. Will share patch for this change. The lock is a different question. The locking of the various drivers differs and I have no idea how you want to handle that. Just sticking the lock into the datastructure and then not making use of it in the timercounter code and leave it to the callsites does not make sense. Most of the locks are held around timecounter_read. In some instances it is held when cyclecounter is updated standalone or is updated along with timecounter calls. Was thinking if we move the lock in timecounter functions, drivers just have to do locking around its operations on cyclecounter. But then another problem I see is there are variation of locking calls like lock_irqsave, lock_bh, write_lock_irqsave (some using rwlock_t). Should this all locking be left to driver only then? You could have the lock in the struct and protect the inner workings in the related core functions. That might remove locking requirements from some of the callers and the others still have their own thing around it. For drivers having static/fixed cyclecounter, we can rely only on lock inside timecounter. Most of the network drivers update cyclecounter at runtime and they will have to rely on two locks if we add one to timecounter. This may not be efficient for them. Also the lock in timecounter has to be less restrictive (may be seqlock) I guess. Cc'd Mellanox list for inputs on this. I have started feeling that the current approach of drivers managing the locks is the right one so better leave the lock out of timecounter. I agree here, In mlx5 we rely on our own read/write lock to serialize access to mlx5_clock struct (mlx5 timecounter and cyclecounter). the access is not as simple as lock() call time_counter_API unlock() Sometimes we also explicitly update/adjust timecycles counters with mlx5 specific calculations after we read the timecounter all inside our lock. e.g. @mlx5_ptp_adjfreq() write_lock_irqsave(>lock, flags); timecounter_read(>tc); clock->cycles.mult = neg_adj ? clock->nominal_c_mult - diff : clock->nominal_c_mult + diff; write_unlock_irqrestore(>lock, flags); So i don't think it will be a simple task to have a generic thread safe timecounter API, without the need to specifically adjust it for all driver use-cases. Also as said above, in runtime it is not obvious in which context the timecounter will be accessed irq/soft irq/user. let's keep it as is, and let the driver decide which locking scheme is most suitable for it. Yes. Thanks for your inputs Saeed. Regards Sagar Thanks, Saeed. Thanks, tglx -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Creating cyclecounter and lock member in timecounter structure [ Was Re: [RFC 1/4] drm/i915/perf: Add support to correlate GPU timestamp with system time]
On 12/1/2017 2:33 AM, Saeed Mahameed wrote: On Mon, Nov 27, 2017 at 2:05 AM, Sagar Arun Kamble wrote: On 11/24/2017 7:01 PM, Thomas Gleixner wrote: On Fri, 24 Nov 2017, Sagar Arun Kamble wrote: On 11/24/2017 12:29 AM, Thomas Gleixner wrote: On Thu, 23 Nov 2017, Sagar Arun Kamble wrote: We needed inputs on possible optimization that can be done to timecounter/cyclecounter structures/usage. This mail is in response to review of patch https://patchwork.freedesktop.org/patch/188448/. As Chris's observation below, about dozen of timecounter users in the kernel have below structures defined individually: spinlock_t lock; struct cyclecounter cc; struct timecounter tc; Can we move lock and cc to tc? That way it will be convenient. Also it will allow unifying the locking/overflow watchdog handling across all drivers. Looks like none of the timecounter usage sites has a real need to separate timecounter and cyclecounter. Yes. Will share patch for this change. The lock is a different question. The locking of the various drivers differs and I have no idea how you want to handle that. Just sticking the lock into the datastructure and then not making use of it in the timercounter code and leave it to the callsites does not make sense. Most of the locks are held around timecounter_read. In some instances it is held when cyclecounter is updated standalone or is updated along with timecounter calls. Was thinking if we move the lock in timecounter functions, drivers just have to do locking around its operations on cyclecounter. But then another problem I see is there are variation of locking calls like lock_irqsave, lock_bh, write_lock_irqsave (some using rwlock_t). Should this all locking be left to driver only then? You could have the lock in the struct and protect the inner workings in the related core functions. That might remove locking requirements from some of the callers and the others still have their own thing around it. For drivers having static/fixed cyclecounter, we can rely only on lock inside timecounter. Most of the network drivers update cyclecounter at runtime and they will have to rely on two locks if we add one to timecounter. This may not be efficient for them. Also the lock in timecounter has to be less restrictive (may be seqlock) I guess. Cc'd Mellanox list for inputs on this. I have started feeling that the current approach of drivers managing the locks is the right one so better leave the lock out of timecounter. I agree here, In mlx5 we rely on our own read/write lock to serialize access to mlx5_clock struct (mlx5 timecounter and cyclecounter). the access is not as simple as lock() call time_counter_API unlock() Sometimes we also explicitly update/adjust timecycles counters with mlx5 specific calculations after we read the timecounter all inside our lock. e.g. @mlx5_ptp_adjfreq() write_lock_irqsave(>lock, flags); timecounter_read(>tc); clock->cycles.mult = neg_adj ? clock->nominal_c_mult - diff : clock->nominal_c_mult + diff; write_unlock_irqrestore(>lock, flags); So i don't think it will be a simple task to have a generic thread safe timecounter API, without the need to specifically adjust it for all driver use-cases. Also as said above, in runtime it is not obvious in which context the timecounter will be accessed irq/soft irq/user. let's keep it as is, and let the driver decide which locking scheme is most suitable for it. Yes. Thanks for your inputs Saeed. Regards Sagar Thanks, Saeed. Thanks, tglx -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Creating cyclecounter and lock member in timecounter structure [ Was Re: [RFC 1/4] drm/i915/perf: Add support to correlate GPU timestamp with system time]
On 11/24/2017 7:01 PM, Thomas Gleixner wrote: On Fri, 24 Nov 2017, Sagar Arun Kamble wrote: On 11/24/2017 12:29 AM, Thomas Gleixner wrote: On Thu, 23 Nov 2017, Sagar Arun Kamble wrote: We needed inputs on possible optimization that can be done to timecounter/cyclecounter structures/usage. This mail is in response to review of patch https://patchwork.freedesktop.org/patch/188448/. As Chris's observation below, about dozen of timecounter users in the kernel have below structures defined individually: spinlock_t lock; struct cyclecounter cc; struct timecounter tc; Can we move lock and cc to tc? That way it will be convenient. Also it will allow unifying the locking/overflow watchdog handling across all drivers. Looks like none of the timecounter usage sites has a real need to separate timecounter and cyclecounter. Yes. Will share patch for this change. The lock is a different question. The locking of the various drivers differs and I have no idea how you want to handle that. Just sticking the lock into the datastructure and then not making use of it in the timercounter code and leave it to the callsites does not make sense. Most of the locks are held around timecounter_read. In some instances it is held when cyclecounter is updated standalone or is updated along with timecounter calls. Was thinking if we move the lock in timecounter functions, drivers just have to do locking around its operations on cyclecounter. But then another problem I see is there are variation of locking calls like lock_irqsave, lock_bh, write_lock_irqsave (some using rwlock_t). Should this all locking be left to driver only then? You could have the lock in the struct and protect the inner workings in the related core functions. That might remove locking requirements from some of the callers and the others still have their own thing around it. For drivers having static/fixed cyclecounter, we can rely only on lock inside timecounter. Most of the network drivers update cyclecounter at runtime and they will have to rely on two locks if we add one to timecounter. This may not be efficient for them. Also the lock in timecounter has to be less restrictive (may be seqlock) I guess. Cc'd Mellanox list for inputs on this. I have started feeling that the current approach of drivers managing the locks is the right one so better leave the lock out of timecounter. Thanks, tglx
Re: Creating cyclecounter and lock member in timecounter structure [ Was Re: [RFC 1/4] drm/i915/perf: Add support to correlate GPU timestamp with system time]
On 11/24/2017 7:01 PM, Thomas Gleixner wrote: On Fri, 24 Nov 2017, Sagar Arun Kamble wrote: On 11/24/2017 12:29 AM, Thomas Gleixner wrote: On Thu, 23 Nov 2017, Sagar Arun Kamble wrote: We needed inputs on possible optimization that can be done to timecounter/cyclecounter structures/usage. This mail is in response to review of patch https://patchwork.freedesktop.org/patch/188448/. As Chris's observation below, about dozen of timecounter users in the kernel have below structures defined individually: spinlock_t lock; struct cyclecounter cc; struct timecounter tc; Can we move lock and cc to tc? That way it will be convenient. Also it will allow unifying the locking/overflow watchdog handling across all drivers. Looks like none of the timecounter usage sites has a real need to separate timecounter and cyclecounter. Yes. Will share patch for this change. The lock is a different question. The locking of the various drivers differs and I have no idea how you want to handle that. Just sticking the lock into the datastructure and then not making use of it in the timercounter code and leave it to the callsites does not make sense. Most of the locks are held around timecounter_read. In some instances it is held when cyclecounter is updated standalone or is updated along with timecounter calls. Was thinking if we move the lock in timecounter functions, drivers just have to do locking around its operations on cyclecounter. But then another problem I see is there are variation of locking calls like lock_irqsave, lock_bh, write_lock_irqsave (some using rwlock_t). Should this all locking be left to driver only then? You could have the lock in the struct and protect the inner workings in the related core functions. That might remove locking requirements from some of the callers and the others still have their own thing around it. For drivers having static/fixed cyclecounter, we can rely only on lock inside timecounter. Most of the network drivers update cyclecounter at runtime and they will have to rely on two locks if we add one to timecounter. This may not be efficient for them. Also the lock in timecounter has to be less restrictive (may be seqlock) I guess. Cc'd Mellanox list for inputs on this. I have started feeling that the current approach of drivers managing the locks is the right one so better leave the lock out of timecounter. Thanks, tglx
[PATCH 1/1] timecounter: Make cyclecounter struct part of timecounter struct
There is no real need for the users of timecounters to define cyclecounter and timecounter variables separately. Since timecounter will always be based on cyclecounter, have cyclecounter struct as member of timecounter struct. Suggested-by: Chris Wilson <ch...@chris-wilson.co.uk> Signed-off-by: Sagar Arun Kamble <sagar.a.kam...@intel.com> Cc: John Stultz <john.stu...@linaro.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Stephen Boyd <sb...@codeaurora.org> Cc: linux-kernel@vger.kernel.org --- arch/microblaze/kernel/timer.c | 20 ++--- drivers/clocksource/arm_arch_timer.c | 19 ++-- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 9 +++--- drivers/net/ethernet/amd/xgbe/xgbe.h | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x.h| 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 20 ++--- drivers/net/ethernet/freescale/fec.h | 1 - drivers/net/ethernet/freescale/fec_ptp.c | 31 ++- drivers/net/ethernet/intel/e1000e/e1000.h | 1 - drivers/net/ethernet/intel/e1000e/netdev.c | 27 - drivers/net/ethernet/intel/e1000e/ptp.c| 2 +- drivers/net/ethernet/intel/igb/igb.h | 1 - drivers/net/ethernet/intel/igb/igb_ptp.c | 25 drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 - drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 17 +-- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 28 - drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - drivers/net/ethernet/mellanox/mlx5/core/en.h | 1 - drivers/net/ethernet/mellanox/mlx5/core/en_clock.c | 33 ++-- drivers/net/ethernet/qlogic/qede/qede_ptp.c| 20 ++--- drivers/net/ethernet/ti/cpts.c | 35 +++--- drivers/net/ethernet/ti/cpts.h | 1 - include/linux/timecounter.h| 4 +-- include/sound/hdaudio.h| 1 - kernel/time/timecounter.c | 28 - sound/hda/hdac_stream.c| 7 +++-- 27 files changed, 160 insertions(+), 178 deletions(-) diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 7de941c..b7f89e9 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -199,27 +199,25 @@ static u64 xilinx_read(struct clocksource *cs) return (u64)xilinx_clock_read(); } -static struct timecounter xilinx_tc = { - .cc = NULL, -}; - static u64 xilinx_cc_read(const struct cyclecounter *cc) { return xilinx_read(NULL); } -static struct cyclecounter xilinx_cc = { - .read = xilinx_cc_read, - .mask = CLOCKSOURCE_MASK(32), - .shift = 8, +static struct timecounter xilinx_tc = { + .cc.read = xilinx_cc_read, + .cc.mask = CLOCKSOURCE_MASK(32), + .cc.mult = 0, + .cc.shift = 8, }; static int __init init_xilinx_timecounter(void) { - xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC, - xilinx_cc.shift); + struct cyclecounter *cc = _tc.cc; + + cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift); - timecounter_init(_tc, _cc, sched_clock()); + timecounter_init(_tc, sched_clock()); return 0; } diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index fd4b7f6..1d60ba0 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -177,11 +177,6 @@ static u64 arch_counter_read_cc(const struct cyclecounter *cc) .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static struct cyclecounter cyclecounter __ro_after_init = { - .read = arch_counter_read_cc, - .mask = CLOCKSOURCE_MASK(56), -}; - struct ate_acpi_oem_info { char oem_id[ACPI_OEM_ID_SIZE + 1]; char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; @@ -877,7 +872,10 @@ static u64 arch_counter_get_cntvct_mem(void) return ((u64) vct_hi << 32) | vct_lo; } -static struct arch_timer_kvm_info arch_timer_kvm_info; +static struct arch_timer_kvm_info arch_timer_kvm_info = { + .timecounter.cc.read = arch_counter_read_cc, + .timecounter.cc.mask = CLOCKSOURCE_MASK(56), +}; struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) { @@ -887,6 +885,7 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) static void __init arch_counter_register(unsigned type) { u64 start_count; + struct cyclecounter *cc = _timer_kvm_info.timecounter.cc; /* Register the CP15 based counter if we have one */ if (type & ARCH_TIMER_TYPE_CP15) { @@ -905,10 +904,10 @@ static void __init arch_counter_register(unsigned t
[PATCH 1/1] timecounter: Make cyclecounter struct part of timecounter struct
There is no real need for the users of timecounters to define cyclecounter and timecounter variables separately. Since timecounter will always be based on cyclecounter, have cyclecounter struct as member of timecounter struct. Suggested-by: Chris Wilson Signed-off-by: Sagar Arun Kamble Cc: John Stultz Cc: Thomas Gleixner Cc: Stephen Boyd Cc: linux-kernel@vger.kernel.org --- arch/microblaze/kernel/timer.c | 20 ++--- drivers/clocksource/arm_arch_timer.c | 19 ++-- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +- drivers/net/ethernet/amd/xgbe/xgbe-ptp.c | 9 +++--- drivers/net/ethernet/amd/xgbe/xgbe.h | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x.h| 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 20 ++--- drivers/net/ethernet/freescale/fec.h | 1 - drivers/net/ethernet/freescale/fec_ptp.c | 31 ++- drivers/net/ethernet/intel/e1000e/e1000.h | 1 - drivers/net/ethernet/intel/e1000e/netdev.c | 27 - drivers/net/ethernet/intel/e1000e/ptp.c| 2 +- drivers/net/ethernet/intel/igb/igb.h | 1 - drivers/net/ethernet/intel/igb/igb_ptp.c | 25 drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 - drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 17 +-- drivers/net/ethernet/mellanox/mlx4/en_clock.c | 28 - drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - drivers/net/ethernet/mellanox/mlx5/core/en.h | 1 - drivers/net/ethernet/mellanox/mlx5/core/en_clock.c | 33 ++-- drivers/net/ethernet/qlogic/qede/qede_ptp.c| 20 ++--- drivers/net/ethernet/ti/cpts.c | 35 +++--- drivers/net/ethernet/ti/cpts.h | 1 - include/linux/timecounter.h| 4 +-- include/sound/hdaudio.h| 1 - kernel/time/timecounter.c | 28 - sound/hda/hdac_stream.c| 7 +++-- 27 files changed, 160 insertions(+), 178 deletions(-) diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index 7de941c..b7f89e9 100644 --- a/arch/microblaze/kernel/timer.c +++ b/arch/microblaze/kernel/timer.c @@ -199,27 +199,25 @@ static u64 xilinx_read(struct clocksource *cs) return (u64)xilinx_clock_read(); } -static struct timecounter xilinx_tc = { - .cc = NULL, -}; - static u64 xilinx_cc_read(const struct cyclecounter *cc) { return xilinx_read(NULL); } -static struct cyclecounter xilinx_cc = { - .read = xilinx_cc_read, - .mask = CLOCKSOURCE_MASK(32), - .shift = 8, +static struct timecounter xilinx_tc = { + .cc.read = xilinx_cc_read, + .cc.mask = CLOCKSOURCE_MASK(32), + .cc.mult = 0, + .cc.shift = 8, }; static int __init init_xilinx_timecounter(void) { - xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC, - xilinx_cc.shift); + struct cyclecounter *cc = _tc.cc; + + cc->mult = div_sc(timer_clock_freq, NSEC_PER_SEC, cc->shift); - timecounter_init(_tc, _cc, sched_clock()); + timecounter_init(_tc, sched_clock()); return 0; } diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index fd4b7f6..1d60ba0 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -177,11 +177,6 @@ static u64 arch_counter_read_cc(const struct cyclecounter *cc) .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static struct cyclecounter cyclecounter __ro_after_init = { - .read = arch_counter_read_cc, - .mask = CLOCKSOURCE_MASK(56), -}; - struct ate_acpi_oem_info { char oem_id[ACPI_OEM_ID_SIZE + 1]; char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1]; @@ -877,7 +872,10 @@ static u64 arch_counter_get_cntvct_mem(void) return ((u64) vct_hi << 32) | vct_lo; } -static struct arch_timer_kvm_info arch_timer_kvm_info; +static struct arch_timer_kvm_info arch_timer_kvm_info = { + .timecounter.cc.read = arch_counter_read_cc, + .timecounter.cc.mask = CLOCKSOURCE_MASK(56), +}; struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) { @@ -887,6 +885,7 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void) static void __init arch_counter_register(unsigned type) { u64 start_count; + struct cyclecounter *cc = _timer_kvm_info.timecounter.cc; /* Register the CP15 based counter if we have one */ if (type & ARCH_TIMER_TYPE_CP15) { @@ -905,10 +904,10 @@ static void __init arch_counter_register(unsigned type) clocksource_counter.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP; start_count = arch_timer_read_counter(); clocksource_regi
Re: Creating cyclecounter and lock member in timecounter structure [ Was Re: [RFC 1/4] drm/i915/perf: Add support to correlate GPU timestamp with system time]
On 11/24/2017 12:29 AM, Thomas Gleixner wrote: On Thu, 23 Nov 2017, Sagar Arun Kamble wrote: We needed inputs on possible optimization that can be done to timecounter/cyclecounter structures/usage. This mail is in response to review of patch https://patchwork.freedesktop.org/patch/188448/. As Chris's observation below, about dozen of timecounter users in the kernel have below structures defined individually: spinlock_t lock; struct cyclecounter cc; struct timecounter tc; Can we move lock and cc to tc? That way it will be convenient. Also it will allow unifying the locking/overflow watchdog handling across all drivers. Looks like none of the timecounter usage sites has a real need to separate timecounter and cyclecounter. Yes. Will share patch for this change. The lock is a different question. The locking of the various drivers differs and I have no idea how you want to handle that. Just sticking the lock into the datastructure and then not making use of it in the timercounter code and leave it to the callsites does not make sense. Most of the locks are held around timecounter_read. In some instances it is held when cyclecounter is updated standalone or is updated along with timecounter calls. Was thinking if we move the lock in timecounter functions, drivers just have to do locking around its operations on cyclecounter. But then another problem I see is there are variation of locking calls like lock_irqsave, lock_bh, write_lock_irqsave (some using rwlock_t). Should this all locking be left to driver only then? Thanks, tglx Thanks Sagar
Re: Creating cyclecounter and lock member in timecounter structure [ Was Re: [RFC 1/4] drm/i915/perf: Add support to correlate GPU timestamp with system time]
On 11/24/2017 12:29 AM, Thomas Gleixner wrote: On Thu, 23 Nov 2017, Sagar Arun Kamble wrote: We needed inputs on possible optimization that can be done to timecounter/cyclecounter structures/usage. This mail is in response to review of patch https://patchwork.freedesktop.org/patch/188448/. As Chris's observation below, about dozen of timecounter users in the kernel have below structures defined individually: spinlock_t lock; struct cyclecounter cc; struct timecounter tc; Can we move lock and cc to tc? That way it will be convenient. Also it will allow unifying the locking/overflow watchdog handling across all drivers. Looks like none of the timecounter usage sites has a real need to separate timecounter and cyclecounter. Yes. Will share patch for this change. The lock is a different question. The locking of the various drivers differs and I have no idea how you want to handle that. Just sticking the lock into the datastructure and then not making use of it in the timercounter code and leave it to the callsites does not make sense. Most of the locks are held around timecounter_read. In some instances it is held when cyclecounter is updated standalone or is updated along with timecounter calls. Was thinking if we move the lock in timecounter functions, drivers just have to do locking around its operations on cyclecounter. But then another problem I see is there are variation of locking calls like lock_irqsave, lock_bh, write_lock_irqsave (some using rwlock_t). Should this all locking be left to driver only then? Thanks, tglx Thanks Sagar
Creating cyclecounter and lock member in timecounter structure [ Was Re: [RFC 1/4] drm/i915/perf: Add support to correlate GPU timestamp with system time]
Hi, We needed inputs on possible optimization that can be done to timecounter/cyclecounter structures/usage. This mail is in response to review of patch https://patchwork.freedesktop.org/patch/188448/. As Chris's observation below, about dozen of timecounter users in the kernel have below structures defined individually: spinlock_t lock; struct cyclecounter cc; struct timecounter tc; Can we move lock and cc to tc? That way it will be convenient. Also it will allow unifying the locking/overflow watchdog handling across all drivers. Please suggest. Thanks Sagar On 11/15/2017 5:55 PM, Chris Wilson wrote: Quoting Sagar Arun Kamble (2017-11-15 12:13:51) #include #include @@ -2149,6 +2150,14 @@ struct i915_perf_stream { * @oa_config: The OA configuration used by the stream. */ struct i915_oa_config *oa_config; + + /** +* System time correlation variables. +*/ + struct cyclecounter cc; + spinlock_t systime_lock; + struct timespec64 start_systime; + struct timecounter tc; This pattern is repeated a lot by struct timecounter users. (I'm still trying to understand why the common case is not catered for by a convenience timecounter api.) }; /** diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 00be015..72ddc34 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -192,6 +192,7 @@ */ #include +#include #include #include @@ -2391,6 +2392,56 @@ static unsigned int i915_perf_poll(struct file *file, poll_table *wait) } /** + * i915_cyclecounter_read - read raw cycle/timestamp counter + * @cc: cyclecounter structure + */ +static u64 i915_cyclecounter_read(const struct cyclecounter *cc) +{ + struct i915_perf_stream *stream = container_of(cc, typeof(*stream), cc); + struct drm_i915_private *dev_priv = stream->dev_priv; + u64 ts_count; + + intel_runtime_pm_get(dev_priv); + ts_count = I915_READ64_2x32(GEN4_TIMESTAMP, + GEN7_TIMESTAMP_UDW); + intel_runtime_pm_put(dev_priv); + + return ts_count; +} + +static void i915_perf_init_cyclecounter(struct i915_perf_stream *stream) +{ + struct drm_i915_private *dev_priv = stream->dev_priv; + int cs_ts_freq = dev_priv->perf.oa.timestamp_frequency; + struct cyclecounter *cc = >cc; + u32 maxsec; + + cc->read = i915_cyclecounter_read; + cc->mask = CYCLECOUNTER_MASK(CS_TIMESTAMP_WIDTH(dev_priv)); + maxsec = cc->mask / cs_ts_freq; + + clocks_calc_mult_shift(>mult, >shift, cs_ts_freq, + NSEC_PER_SEC, maxsec); +} + +static void i915_perf_init_timecounter(struct i915_perf_stream *stream) +{ +#define SYSTIME_START_OFFSET 35 /* Counter read takes about 350us */ + unsigned long flags; + u64 ns; + + i915_perf_init_cyclecounter(stream); + spin_lock_init(>systime_lock); + + getnstimeofday64(>start_systime); + ns = timespec64_to_ns(>start_systime) + SYSTIME_START_OFFSET; Use ktime directly. Or else Arnd will be back with a patch to fix it. (All non-ktime interfaces are effectively deprecated; obsolete for drivers.) + spin_lock_irqsave(>systime_lock, flags); + timecounter_init(>tc, >cc, ns); + spin_unlock_irqrestore(>systime_lock, flags); +} + +/** * i915_perf_enable_locked - handle `I915_PERF_IOCTL_ENABLE` ioctl * @stream: A disabled i915 perf stream * @@ -2408,6 +2459,8 @@ static void i915_perf_enable_locked(struct i915_perf_stream *stream) /* Allow stream->ops->enable() to refer to this */ stream->enabled = true; + i915_perf_init_timecounter(stream); + if (stream->ops->enable) stream->ops->enable(stream); } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index cfdf4f8..e7e6966 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8882,6 +8882,12 @@ enum skl_power_gate { /* Gen4+ Timestamp and Pipe Frame time stamp registers */ #define GEN4_TIMESTAMP _MMIO(0x2358) +#define GEN7_TIMESTAMP_UDW _MMIO(0x235C) +#define PRE_GEN7_TIMESTAMP_WIDTH 32 +#define GEN7_TIMESTAMP_WIDTH 36 +#define CS_TIMESTAMP_WIDTH(dev_priv) \ + (INTEL_GEN(dev_priv) < 7 ? PRE_GEN7_TIMESTAMP_WIDTH : \ + GEN7_TIMESTAMP_WIDTH) s/PRE_GEN7/GEN4/ would be consistent. If you really want to add support for earlier, I9XX_. Ok. I can accept the justification, and we are not the only ones who do the cyclecounter -> timecounter correction like this. -Chris
Creating cyclecounter and lock member in timecounter structure [ Was Re: [RFC 1/4] drm/i915/perf: Add support to correlate GPU timestamp with system time]
Hi, We needed inputs on possible optimization that can be done to timecounter/cyclecounter structures/usage. This mail is in response to review of patch https://patchwork.freedesktop.org/patch/188448/. As Chris's observation below, about dozen of timecounter users in the kernel have below structures defined individually: spinlock_t lock; struct cyclecounter cc; struct timecounter tc; Can we move lock and cc to tc? That way it will be convenient. Also it will allow unifying the locking/overflow watchdog handling across all drivers. Please suggest. Thanks Sagar On 11/15/2017 5:55 PM, Chris Wilson wrote: Quoting Sagar Arun Kamble (2017-11-15 12:13:51) #include #include @@ -2149,6 +2150,14 @@ struct i915_perf_stream { * @oa_config: The OA configuration used by the stream. */ struct i915_oa_config *oa_config; + + /** +* System time correlation variables. +*/ + struct cyclecounter cc; + spinlock_t systime_lock; + struct timespec64 start_systime; + struct timecounter tc; This pattern is repeated a lot by struct timecounter users. (I'm still trying to understand why the common case is not catered for by a convenience timecounter api.) }; /** diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 00be015..72ddc34 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -192,6 +192,7 @@ */ #include +#include #include #include @@ -2391,6 +2392,56 @@ static unsigned int i915_perf_poll(struct file *file, poll_table *wait) } /** + * i915_cyclecounter_read - read raw cycle/timestamp counter + * @cc: cyclecounter structure + */ +static u64 i915_cyclecounter_read(const struct cyclecounter *cc) +{ + struct i915_perf_stream *stream = container_of(cc, typeof(*stream), cc); + struct drm_i915_private *dev_priv = stream->dev_priv; + u64 ts_count; + + intel_runtime_pm_get(dev_priv); + ts_count = I915_READ64_2x32(GEN4_TIMESTAMP, + GEN7_TIMESTAMP_UDW); + intel_runtime_pm_put(dev_priv); + + return ts_count; +} + +static void i915_perf_init_cyclecounter(struct i915_perf_stream *stream) +{ + struct drm_i915_private *dev_priv = stream->dev_priv; + int cs_ts_freq = dev_priv->perf.oa.timestamp_frequency; + struct cyclecounter *cc = >cc; + u32 maxsec; + + cc->read = i915_cyclecounter_read; + cc->mask = CYCLECOUNTER_MASK(CS_TIMESTAMP_WIDTH(dev_priv)); + maxsec = cc->mask / cs_ts_freq; + + clocks_calc_mult_shift(>mult, >shift, cs_ts_freq, + NSEC_PER_SEC, maxsec); +} + +static void i915_perf_init_timecounter(struct i915_perf_stream *stream) +{ +#define SYSTIME_START_OFFSET 35 /* Counter read takes about 350us */ + unsigned long flags; + u64 ns; + + i915_perf_init_cyclecounter(stream); + spin_lock_init(>systime_lock); + + getnstimeofday64(>start_systime); + ns = timespec64_to_ns(>start_systime) + SYSTIME_START_OFFSET; Use ktime directly. Or else Arnd will be back with a patch to fix it. (All non-ktime interfaces are effectively deprecated; obsolete for drivers.) + spin_lock_irqsave(>systime_lock, flags); + timecounter_init(>tc, >cc, ns); + spin_unlock_irqrestore(>systime_lock, flags); +} + +/** * i915_perf_enable_locked - handle `I915_PERF_IOCTL_ENABLE` ioctl * @stream: A disabled i915 perf stream * @@ -2408,6 +2459,8 @@ static void i915_perf_enable_locked(struct i915_perf_stream *stream) /* Allow stream->ops->enable() to refer to this */ stream->enabled = true; + i915_perf_init_timecounter(stream); + if (stream->ops->enable) stream->ops->enable(stream); } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index cfdf4f8..e7e6966 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8882,6 +8882,12 @@ enum skl_power_gate { /* Gen4+ Timestamp and Pipe Frame time stamp registers */ #define GEN4_TIMESTAMP _MMIO(0x2358) +#define GEN7_TIMESTAMP_UDW _MMIO(0x235C) +#define PRE_GEN7_TIMESTAMP_WIDTH 32 +#define GEN7_TIMESTAMP_WIDTH 36 +#define CS_TIMESTAMP_WIDTH(dev_priv) \ + (INTEL_GEN(dev_priv) < 7 ? PRE_GEN7_TIMESTAMP_WIDTH : \ + GEN7_TIMESTAMP_WIDTH) s/PRE_GEN7/GEN4/ would be consistent. If you really want to add support for earlier, I9XX_. Ok. I can accept the justification, and we are not the only ones who do the cyclecounter -> timecounter correction like this. -Chris
[PATCH 1/2] iommu: Disable preemption around use of this_cpu_ptr()
From: Chris WilsonBetween acquiring the this_cpu_ptr() and using it, ideally we don't want to be preempted and work on another CPU's private data. this_cpu_ptr() checks whether or not preemption is disable, and get_cpu_ptr() provides a convenient wrapper for operating on the cpu ptr inside a preemption disabled critical section (which currently is provided by the spinlock). Indeed if we disable preemption around this_cpu_ptr, we do not need the CPU local spinlock - so long as take care that no other CPU is running that code as do perform the cross-CPU cache flushing and teardown, but that is a subject for another patch. [ 167.997877] BUG: using smp_processor_id() in preemptible [] code: usb-storage/216 [ 167.997940] caller is debug_smp_processor_id+0x17/0x20 [ 167.997945] CPU: 7 PID: 216 Comm: usb-storage Tainted: G U 4.7.0-rc1-gfxbench-RO_Patchwork_1057+ #1 [ 167.997948] Hardware name: Hewlett-Packard HP Pro 3500 Series/2ABF, BIOS 8.11 10/24/2012 [ 167.997951] 880118b7f9c8 8140dca5 0007 [ 167.997958] 81a3a7e9 880118b7f9f8 8142a927 [ 167.997965] 8800d499ed58 0001 000f 880118b7fa08 [ 167.997971] Call Trace: [ 167.997977] [] dump_stack+0x67/0x92 [ 167.997981] [] check_preemption_disabled+0xd7/0xe0 [ 167.997985] [] debug_smp_processor_id+0x17/0x20 [ 167.997990] [] alloc_iova_fast+0xb7/0x210 [ 167.997994] [] intel_alloc_iova+0x7f/0xd0 [ 167.997998] [] intel_map_sg+0xbd/0x240 [ 167.998002] [] ? debug_lockdep_rcu_enabled+0x1d/0x20 [ 167.998009] [] usb_hcd_map_urb_for_dma+0x4b9/0x5a0 [ 167.998013] [] usb_hcd_submit_urb+0xe9/0xaa0 [ 167.998017] [] ? mark_held_locks+0x6f/0xa0 [ 167.998022] [] ? __raw_spin_lock_init+0x1c/0x50 [ 167.998025] [] ? debug_lockdep_rcu_enabled+0x1d/0x20 [ 167.998028] [] usb_submit_urb+0x3f3/0x5a0 [ 167.998032] [] ? trace_hardirqs_on_caller+0x122/0x1b0 [ 167.998035] [] usb_sg_wait+0x67/0x150 [ 167.998039] [] usb_stor_bulk_transfer_sglist.part.3+0x82/0xd0 [ 167.998042] [] usb_stor_bulk_srb+0x4c/0x60 [ 167.998045] [] usb_stor_Bulk_transport+0x17e/0x420 [ 167.998049] [] usb_stor_invoke_transport+0x242/0x540 [ 167.998052] [] ? debug_lockdep_rcu_enabled+0x1d/0x20 [ 167.998058] [] usb_stor_transparent_scsi_command+0x9/0x10 [ 167.998061] [] usb_stor_control_thread+0x158/0x260 [ 167.998064] [] ? fill_inquiry_response+0x20/0x20 [ 167.998067] [] ? fill_inquiry_response+0x20/0x20 [ 167.998071] [] kthread+0xea/0x100 [ 167.998078] [] ret_from_fork+0x1f/0x40 [ 167.998081] [] ? kthread_create_on_node+0x1f0/0x1f0 v2: convert preempt_disable(); var = this_cpu_ptr() to var = get_cpu_ptr() v3: Actually use get_cpu_ptr (not get_cpu_var). Drop the spinlock removal, concentrate on the immediate bug fix. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96293 Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Cc: Joerg Roedel Cc: io...@lists.linux-foundation.org Cc: linux-kernel@vger.kernel.org Reviewed-by: Joonas Lahtinen --- drivers/iommu/iova.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index ba764a0..e23001b 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -420,8 +420,10 @@ retry: /* Try replenishing IOVAs by flushing rcache. */ flushed_rcache = true; + preempt_disable(); for_each_online_cpu(cpu) free_cpu_cached_iovas(cpu, iovad); + preempt_enable(); goto retry; } @@ -749,7 +751,7 @@ static bool __iova_rcache_insert(struct iova_domain *iovad, bool can_insert = false; unsigned long flags; - cpu_rcache = this_cpu_ptr(rcache->cpu_rcaches); + cpu_rcache = get_cpu_ptr(rcache->cpu_rcaches); spin_lock_irqsave(_rcache->lock, flags); if (!iova_magazine_full(cpu_rcache->loaded)) { @@ -779,6 +781,7 @@ static bool __iova_rcache_insert(struct iova_domain *iovad, iova_magazine_push(cpu_rcache->loaded, iova_pfn); spin_unlock_irqrestore(_rcache->lock, flags); + put_cpu_ptr(rcache->cpu_rcaches); if (mag_to_free) { iova_magazine_free_pfns(mag_to_free, iovad); @@ -812,7 +815,7 @@ static unsigned long __iova_rcache_get(struct iova_rcache *rcache, bool has_pfn = false; unsigned long flags; - cpu_rcache = this_cpu_ptr(rcache->cpu_rcaches); + cpu_rcache = get_cpu_ptr(rcache->cpu_rcaches); spin_lock_irqsave(_rcache->lock, flags); if (!iova_magazine_empty(cpu_rcache->loaded)) { @@ -834,6 +837,7 @@ static unsigned long __iova_rcache_get(struct iova_rcache *rcache, iova_pfn =
[PATCH 1/2] iommu: Disable preemption around use of this_cpu_ptr()
From: Chris Wilson Between acquiring the this_cpu_ptr() and using it, ideally we don't want to be preempted and work on another CPU's private data. this_cpu_ptr() checks whether or not preemption is disable, and get_cpu_ptr() provides a convenient wrapper for operating on the cpu ptr inside a preemption disabled critical section (which currently is provided by the spinlock). Indeed if we disable preemption around this_cpu_ptr, we do not need the CPU local spinlock - so long as take care that no other CPU is running that code as do perform the cross-CPU cache flushing and teardown, but that is a subject for another patch. [ 167.997877] BUG: using smp_processor_id() in preemptible [] code: usb-storage/216 [ 167.997940] caller is debug_smp_processor_id+0x17/0x20 [ 167.997945] CPU: 7 PID: 216 Comm: usb-storage Tainted: G U 4.7.0-rc1-gfxbench-RO_Patchwork_1057+ #1 [ 167.997948] Hardware name: Hewlett-Packard HP Pro 3500 Series/2ABF, BIOS 8.11 10/24/2012 [ 167.997951] 880118b7f9c8 8140dca5 0007 [ 167.997958] 81a3a7e9 880118b7f9f8 8142a927 [ 167.997965] 8800d499ed58 0001 000f 880118b7fa08 [ 167.997971] Call Trace: [ 167.997977] [] dump_stack+0x67/0x92 [ 167.997981] [] check_preemption_disabled+0xd7/0xe0 [ 167.997985] [] debug_smp_processor_id+0x17/0x20 [ 167.997990] [] alloc_iova_fast+0xb7/0x210 [ 167.997994] [] intel_alloc_iova+0x7f/0xd0 [ 167.997998] [] intel_map_sg+0xbd/0x240 [ 167.998002] [] ? debug_lockdep_rcu_enabled+0x1d/0x20 [ 167.998009] [] usb_hcd_map_urb_for_dma+0x4b9/0x5a0 [ 167.998013] [] usb_hcd_submit_urb+0xe9/0xaa0 [ 167.998017] [] ? mark_held_locks+0x6f/0xa0 [ 167.998022] [] ? __raw_spin_lock_init+0x1c/0x50 [ 167.998025] [] ? debug_lockdep_rcu_enabled+0x1d/0x20 [ 167.998028] [] usb_submit_urb+0x3f3/0x5a0 [ 167.998032] [] ? trace_hardirqs_on_caller+0x122/0x1b0 [ 167.998035] [] usb_sg_wait+0x67/0x150 [ 167.998039] [] usb_stor_bulk_transfer_sglist.part.3+0x82/0xd0 [ 167.998042] [] usb_stor_bulk_srb+0x4c/0x60 [ 167.998045] [] usb_stor_Bulk_transport+0x17e/0x420 [ 167.998049] [] usb_stor_invoke_transport+0x242/0x540 [ 167.998052] [] ? debug_lockdep_rcu_enabled+0x1d/0x20 [ 167.998058] [] usb_stor_transparent_scsi_command+0x9/0x10 [ 167.998061] [] usb_stor_control_thread+0x158/0x260 [ 167.998064] [] ? fill_inquiry_response+0x20/0x20 [ 167.998067] [] ? fill_inquiry_response+0x20/0x20 [ 167.998071] [] kthread+0xea/0x100 [ 167.998078] [] ret_from_fork+0x1f/0x40 [ 167.998081] [] ? kthread_create_on_node+0x1f0/0x1f0 v2: convert preempt_disable(); var = this_cpu_ptr() to var = get_cpu_ptr() v3: Actually use get_cpu_ptr (not get_cpu_var). Drop the spinlock removal, concentrate on the immediate bug fix. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96293 Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Cc: Joerg Roedel Cc: io...@lists.linux-foundation.org Cc: linux-kernel@vger.kernel.org Reviewed-by: Joonas Lahtinen --- drivers/iommu/iova.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index ba764a0..e23001b 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -420,8 +420,10 @@ retry: /* Try replenishing IOVAs by flushing rcache. */ flushed_rcache = true; + preempt_disable(); for_each_online_cpu(cpu) free_cpu_cached_iovas(cpu, iovad); + preempt_enable(); goto retry; } @@ -749,7 +751,7 @@ static bool __iova_rcache_insert(struct iova_domain *iovad, bool can_insert = false; unsigned long flags; - cpu_rcache = this_cpu_ptr(rcache->cpu_rcaches); + cpu_rcache = get_cpu_ptr(rcache->cpu_rcaches); spin_lock_irqsave(_rcache->lock, flags); if (!iova_magazine_full(cpu_rcache->loaded)) { @@ -779,6 +781,7 @@ static bool __iova_rcache_insert(struct iova_domain *iovad, iova_magazine_push(cpu_rcache->loaded, iova_pfn); spin_unlock_irqrestore(_rcache->lock, flags); + put_cpu_ptr(rcache->cpu_rcaches); if (mag_to_free) { iova_magazine_free_pfns(mag_to_free, iovad); @@ -812,7 +815,7 @@ static unsigned long __iova_rcache_get(struct iova_rcache *rcache, bool has_pfn = false; unsigned long flags; - cpu_rcache = this_cpu_ptr(rcache->cpu_rcaches); + cpu_rcache = get_cpu_ptr(rcache->cpu_rcaches); spin_lock_irqsave(_rcache->lock, flags); if (!iova_magazine_empty(cpu_rcache->loaded)) { @@ -834,6 +837,7 @@ static unsigned long __iova_rcache_get(struct iova_rcache *rcache, iova_pfn = iova_magazine_pop(cpu_rcache->loaded, limit_pfn); spin_unlock_irqrestore(_rcache->lock, flags); + put_cpu_ptr(rcache->cpu_rcaches); return
[PATCH 2/2] iommu: Remove cpu-local spinlock
From: Chris WilsonBy avoiding cross-CPU usage of the per-cpu iova cache, we can forgo having a spinlock inside the per-cpu struct. The only place where we actually may touch another CPU's data is when performing a cache flush after running out of memory. Here, we can instead schedule a task to run on the other CPU to do the flush before trying again. Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Cc: Joerg Roedel Cc: io...@lists.linux-foundation.org Cc: linux-kernel@vger.kernel.org Reviewed-by: Joonas Lahtinen --- drivers/iommu/iova.c | 29 ++--- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index e23001b..36cdc8e 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -390,6 +390,11 @@ free_iova(struct iova_domain *iovad, unsigned long pfn) } EXPORT_SYMBOL_GPL(free_iova); +static void free_this_cached_iovas(void *info) +{ + free_cpu_cached_iovas(smp_processor_id(), info); +} + /** * alloc_iova_fast - allocates an iova from rcache * @iovad: - iova domain in question @@ -413,17 +418,12 @@ alloc_iova_fast(struct iova_domain *iovad, unsigned long size, retry: new_iova = alloc_iova(iovad, size, limit_pfn, true); if (!new_iova) { - unsigned int cpu; - if (flushed_rcache) return 0; /* Try replenishing IOVAs by flushing rcache. */ flushed_rcache = true; - preempt_disable(); - for_each_online_cpu(cpu) - free_cpu_cached_iovas(cpu, iovad); - preempt_enable(); + on_each_cpu(free_this_cached_iovas, iovad, true); goto retry; } @@ -647,7 +647,6 @@ struct iova_magazine { }; struct iova_cpu_rcache { - spinlock_t lock; struct iova_magazine *loaded; struct iova_magazine *prev; }; @@ -729,7 +728,6 @@ static void init_iova_rcaches(struct iova_domain *iovad) continue; for_each_possible_cpu(cpu) { cpu_rcache = per_cpu_ptr(rcache->cpu_rcaches, cpu); - spin_lock_init(_rcache->lock); cpu_rcache->loaded = iova_magazine_alloc(GFP_KERNEL); cpu_rcache->prev = iova_magazine_alloc(GFP_KERNEL); } @@ -749,10 +747,8 @@ static bool __iova_rcache_insert(struct iova_domain *iovad, struct iova_magazine *mag_to_free = NULL; struct iova_cpu_rcache *cpu_rcache; bool can_insert = false; - unsigned long flags; cpu_rcache = get_cpu_ptr(rcache->cpu_rcaches); - spin_lock_irqsave(_rcache->lock, flags); if (!iova_magazine_full(cpu_rcache->loaded)) { can_insert = true; @@ -780,7 +776,6 @@ static bool __iova_rcache_insert(struct iova_domain *iovad, if (can_insert) iova_magazine_push(cpu_rcache->loaded, iova_pfn); - spin_unlock_irqrestore(_rcache->lock, flags); put_cpu_ptr(rcache->cpu_rcaches); if (mag_to_free) { @@ -813,10 +808,8 @@ static unsigned long __iova_rcache_get(struct iova_rcache *rcache, struct iova_cpu_rcache *cpu_rcache; unsigned long iova_pfn = 0; bool has_pfn = false; - unsigned long flags; cpu_rcache = get_cpu_ptr(rcache->cpu_rcaches); - spin_lock_irqsave(_rcache->lock, flags); if (!iova_magazine_empty(cpu_rcache->loaded)) { has_pfn = true; @@ -836,7 +829,6 @@ static unsigned long __iova_rcache_get(struct iova_rcache *rcache, if (has_pfn) iova_pfn = iova_magazine_pop(cpu_rcache->loaded, limit_pfn); - spin_unlock_irqrestore(_rcache->lock, flags); put_cpu_ptr(rcache->cpu_rcaches); return iova_pfn; @@ -866,17 +858,11 @@ static void free_cpu_iova_rcache(unsigned int cpu, struct iova_domain *iovad, struct iova_rcache *rcache) { struct iova_cpu_rcache *cpu_rcache = per_cpu_ptr(rcache->cpu_rcaches, cpu); - unsigned long flags; - - spin_lock_irqsave(_rcache->lock, flags); - iova_magazine_free_pfns(cpu_rcache->loaded, iovad); iova_magazine_free(cpu_rcache->loaded); iova_magazine_free_pfns(cpu_rcache->prev, iovad); iova_magazine_free(cpu_rcache->prev); - - spin_unlock_irqrestore(_rcache->lock, flags); } /* @@ -910,16 +896,13 @@ void free_cpu_cached_iovas(unsigned int cpu, struct iova_domain *iovad) { struct iova_cpu_rcache *cpu_rcache; struct iova_rcache *rcache; - unsigned long flags; int i; for (i = 0; i < IOVA_RANGE_CACHE_MAX_SIZE; ++i) { rcache = >rcaches[i]; cpu_rcache = per_cpu_ptr(rcache->cpu_rcaches,
[PATCH 2/2] iommu: Remove cpu-local spinlock
From: Chris Wilson By avoiding cross-CPU usage of the per-cpu iova cache, we can forgo having a spinlock inside the per-cpu struct. The only place where we actually may touch another CPU's data is when performing a cache flush after running out of memory. Here, we can instead schedule a task to run on the other CPU to do the flush before trying again. Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Cc: Joerg Roedel Cc: io...@lists.linux-foundation.org Cc: linux-kernel@vger.kernel.org Reviewed-by: Joonas Lahtinen --- drivers/iommu/iova.c | 29 ++--- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index e23001b..36cdc8e 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -390,6 +390,11 @@ free_iova(struct iova_domain *iovad, unsigned long pfn) } EXPORT_SYMBOL_GPL(free_iova); +static void free_this_cached_iovas(void *info) +{ + free_cpu_cached_iovas(smp_processor_id(), info); +} + /** * alloc_iova_fast - allocates an iova from rcache * @iovad: - iova domain in question @@ -413,17 +418,12 @@ alloc_iova_fast(struct iova_domain *iovad, unsigned long size, retry: new_iova = alloc_iova(iovad, size, limit_pfn, true); if (!new_iova) { - unsigned int cpu; - if (flushed_rcache) return 0; /* Try replenishing IOVAs by flushing rcache. */ flushed_rcache = true; - preempt_disable(); - for_each_online_cpu(cpu) - free_cpu_cached_iovas(cpu, iovad); - preempt_enable(); + on_each_cpu(free_this_cached_iovas, iovad, true); goto retry; } @@ -647,7 +647,6 @@ struct iova_magazine { }; struct iova_cpu_rcache { - spinlock_t lock; struct iova_magazine *loaded; struct iova_magazine *prev; }; @@ -729,7 +728,6 @@ static void init_iova_rcaches(struct iova_domain *iovad) continue; for_each_possible_cpu(cpu) { cpu_rcache = per_cpu_ptr(rcache->cpu_rcaches, cpu); - spin_lock_init(_rcache->lock); cpu_rcache->loaded = iova_magazine_alloc(GFP_KERNEL); cpu_rcache->prev = iova_magazine_alloc(GFP_KERNEL); } @@ -749,10 +747,8 @@ static bool __iova_rcache_insert(struct iova_domain *iovad, struct iova_magazine *mag_to_free = NULL; struct iova_cpu_rcache *cpu_rcache; bool can_insert = false; - unsigned long flags; cpu_rcache = get_cpu_ptr(rcache->cpu_rcaches); - spin_lock_irqsave(_rcache->lock, flags); if (!iova_magazine_full(cpu_rcache->loaded)) { can_insert = true; @@ -780,7 +776,6 @@ static bool __iova_rcache_insert(struct iova_domain *iovad, if (can_insert) iova_magazine_push(cpu_rcache->loaded, iova_pfn); - spin_unlock_irqrestore(_rcache->lock, flags); put_cpu_ptr(rcache->cpu_rcaches); if (mag_to_free) { @@ -813,10 +808,8 @@ static unsigned long __iova_rcache_get(struct iova_rcache *rcache, struct iova_cpu_rcache *cpu_rcache; unsigned long iova_pfn = 0; bool has_pfn = false; - unsigned long flags; cpu_rcache = get_cpu_ptr(rcache->cpu_rcaches); - spin_lock_irqsave(_rcache->lock, flags); if (!iova_magazine_empty(cpu_rcache->loaded)) { has_pfn = true; @@ -836,7 +829,6 @@ static unsigned long __iova_rcache_get(struct iova_rcache *rcache, if (has_pfn) iova_pfn = iova_magazine_pop(cpu_rcache->loaded, limit_pfn); - spin_unlock_irqrestore(_rcache->lock, flags); put_cpu_ptr(rcache->cpu_rcaches); return iova_pfn; @@ -866,17 +858,11 @@ static void free_cpu_iova_rcache(unsigned int cpu, struct iova_domain *iovad, struct iova_rcache *rcache) { struct iova_cpu_rcache *cpu_rcache = per_cpu_ptr(rcache->cpu_rcaches, cpu); - unsigned long flags; - - spin_lock_irqsave(_rcache->lock, flags); - iova_magazine_free_pfns(cpu_rcache->loaded, iovad); iova_magazine_free(cpu_rcache->loaded); iova_magazine_free_pfns(cpu_rcache->prev, iovad); iova_magazine_free(cpu_rcache->prev); - - spin_unlock_irqrestore(_rcache->lock, flags); } /* @@ -910,16 +896,13 @@ void free_cpu_cached_iovas(unsigned int cpu, struct iova_domain *iovad) { struct iova_cpu_rcache *cpu_rcache; struct iova_rcache *rcache; - unsigned long flags; int i; for (i = 0; i < IOVA_RANGE_CACHE_MAX_SIZE; ++i) { rcache = >rcaches[i]; cpu_rcache = per_cpu_ptr(rcache->cpu_rcaches, cpu); - spin_lock_irqsave(_rcache->lock, flags); iova_magazine_free_pfns(cpu_rcache->loaded, iovad);
Re: [PATCH v2 1/4] drm: Adding new flag to restrict bitmask drm properties as 32 bit type and 32 bit value pair
Adding Rob and Rusty in the review thread. Kindly review these patches for interface being proposed to set color/alpha property of planes modeled after glBlendFunc. http://lists.freedesktop.org/archives/intel-gfx/2014-March/042350.html http://lists.freedesktop.org/archives/intel-gfx/2014-March/042351.html http://lists.freedesktop.org/archives/intel-gfx/2014-March/042352.html http://lists.freedesktop.org/archives/intel-gfx/2014-March/042587.html http://lists.freedesktop.org/archives/intel-gfx/2014-March/042354.html thanks, Sagar On Tue, 2014-03-25 at 20:02 +0530, sagar.a.kam...@intel.com wrote: > From: Sagar Kamble > > With this patch new flag DRM_MODE_PROP_32BIT_PAIR is added that will help > make use > of 64 bit value of bitmask property as two 32 bit values. > > Cc: airl...@linux.ie > Cc: dri-de...@lists.freedesktop.org > Cc: linux-kernel@vger.kernel.org > Signed-off-by: Sagar Kamble > --- > drivers/gpu/drm/drm_crtc.c | 22 -- > include/uapi/drm/drm_mode.h | 3 +++ > 2 files changed, 19 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c > index 4e43fc2..d0d03ec 100644 > --- a/drivers/gpu/drm/drm_crtc.c > +++ b/drivers/gpu/drm/drm_crtc.c > @@ -2993,10 +2993,13 @@ int drm_property_add_enum(struct drm_property > *property, int index, > > /* >* Bitmask enum properties have the additional constraint of values > - * from 0 to 63 > + * from 0 to 63. For properties with 32BIT_PAIR Flag set this constraint > + * range is 0 to 31. >*/ > - if ((property->flags & DRM_MODE_PROP_BITMASK) && (value > 63)) > - return -EINVAL; > + if (property->flags & DRM_MODE_PROP_BITMASK) > + if (((property->flags & DRM_MODE_PROP_32BIT_PAIR) && (value > > 31)) || > + (value > 63)) > + return -EINVAL; > > if (!list_empty(>enum_blob_list)) { > list_for_each_entry(prop_enum, >enum_blob_list, head) > { > @@ -3305,9 +3308,16 @@ static bool drm_property_change_is_valid(struct > drm_property *property, > } else if (property->flags & DRM_MODE_PROP_BITMASK) { > int i; > uint64_t valid_mask = 0; > - for (i = 0; i < property->num_values; i++) > - valid_mask |= (1ULL << property->values[i]); > - return !(value & ~valid_mask); > + uint32_t valid_32bit_mask = 0; > + if (property->flags & DRM_MODE_PROP_32BIT_PAIR) { > + for (i = 0; i < property->num_values; i++) > + valid_32bit_mask |= (1UL << > property->values[i]); > + return !((value & 0x) & ~valid_32bit_mask); > + } else { > + for (i = 0; i < property->num_values; i++) > + valid_mask |= (1ULL << property->values[i]); > + return !(value & ~valid_mask); > + } > } else if (property->flags & DRM_MODE_PROP_BLOB) { > /* Only the driver knows */ > return true; > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h > index f104c26..5e3a7d9 100644 > --- a/include/uapi/drm/drm_mode.h > +++ b/include/uapi/drm/drm_mode.h > @@ -250,6 +250,9 @@ struct drm_mode_get_connector { > #define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */ > #define DRM_MODE_PROP_BLOB (1<<4) > #define DRM_MODE_PROP_BITMASK(1<<5) /* bitmask of enumerated types */ > +#define DRM_MODE_PROP_32BIT_PAIR (1<<6) /* 32 bit bitmask of enumerated types > + * and 32 bit of value of the type */ > + > > struct drm_mode_property_enum { > __u64 value; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 1/4] drm: Adding new flag to restrict bitmask drm properties as 32 bit type and 32 bit value pair
Adding Rob and Rusty in the review thread. Kindly review these patches for interface being proposed to set color/alpha property of planes modeled after glBlendFunc. http://lists.freedesktop.org/archives/intel-gfx/2014-March/042350.html http://lists.freedesktop.org/archives/intel-gfx/2014-March/042351.html http://lists.freedesktop.org/archives/intel-gfx/2014-March/042352.html http://lists.freedesktop.org/archives/intel-gfx/2014-March/042587.html http://lists.freedesktop.org/archives/intel-gfx/2014-March/042354.html thanks, Sagar On Tue, 2014-03-25 at 20:02 +0530, sagar.a.kam...@intel.com wrote: From: Sagar Kamble sagar.a.kam...@intel.com With this patch new flag DRM_MODE_PROP_32BIT_PAIR is added that will help make use of 64 bit value of bitmask property as two 32 bit values. Cc: airl...@linux.ie Cc: dri-de...@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Sagar Kamble sagar.a.kam...@intel.com --- drivers/gpu/drm/drm_crtc.c | 22 -- include/uapi/drm/drm_mode.h | 3 +++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 4e43fc2..d0d03ec 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2993,10 +2993,13 @@ int drm_property_add_enum(struct drm_property *property, int index, /* * Bitmask enum properties have the additional constraint of values - * from 0 to 63 + * from 0 to 63. For properties with 32BIT_PAIR Flag set this constraint + * range is 0 to 31. */ - if ((property-flags DRM_MODE_PROP_BITMASK) (value 63)) - return -EINVAL; + if (property-flags DRM_MODE_PROP_BITMASK) + if (((property-flags DRM_MODE_PROP_32BIT_PAIR) (value 31)) || + (value 63)) + return -EINVAL; if (!list_empty(property-enum_blob_list)) { list_for_each_entry(prop_enum, property-enum_blob_list, head) { @@ -3305,9 +3308,16 @@ static bool drm_property_change_is_valid(struct drm_property *property, } else if (property-flags DRM_MODE_PROP_BITMASK) { int i; uint64_t valid_mask = 0; - for (i = 0; i property-num_values; i++) - valid_mask |= (1ULL property-values[i]); - return !(value ~valid_mask); + uint32_t valid_32bit_mask = 0; + if (property-flags DRM_MODE_PROP_32BIT_PAIR) { + for (i = 0; i property-num_values; i++) + valid_32bit_mask |= (1UL property-values[i]); + return !((value 0x) ~valid_32bit_mask); + } else { + for (i = 0; i property-num_values; i++) + valid_mask |= (1ULL property-values[i]); + return !(value ~valid_mask); + } } else if (property-flags DRM_MODE_PROP_BLOB) { /* Only the driver knows */ return true; diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index f104c26..5e3a7d9 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -250,6 +250,9 @@ struct drm_mode_get_connector { #define DRM_MODE_PROP_ENUM (13) /* enumerated type with text strings */ #define DRM_MODE_PROP_BLOB (14) #define DRM_MODE_PROP_BITMASK(15) /* bitmask of enumerated types */ +#define DRM_MODE_PROP_32BIT_PAIR (16) /* 32 bit bitmask of enumerated types + * and 32 bit of value of the type */ + struct drm_mode_property_enum { __u64 value; -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v4 1/1] drm/i915: Enabling 128x128 and 256x256 ARGB Cursor Support
Gentle reminder for reviewing this and i-g-t patch. On Mon, 2014-03-10 at 17:06 +0530, sagar.a.kam...@intel.com wrote: > From: Sagar Kamble > > With this patch we allow larger cursor planes of sizes 128x128 > and 256x256. > > v2: Added more precise check on size while setting cursor plane. > > v3: Changes related to restructuring cursor size restrictions > and DRM_DEBUG usage. > > v4: Indentation related changes for setting cursor control and > implementing DRM_CAP_CURSOR_WIDTH and DRM_CAP_CURSOR_HEIGHT > > Testcase: igt/kms_cursor_crc > Cc: Daniel Vetter > Cc: Jani Nikula > Cc: David Airlie > Cc: dri-de...@lists.freedesktop.org > Cc: linux-kernel@vger.kernel.org > Signed-off-by: G, Pallavi > Signed-off-by: Sagar Kamble > --- > drivers/gpu/drm/i915/i915_reg.h | 4 +++ > drivers/gpu/drm/i915/intel_display.c | 53 > > drivers/gpu/drm/i915/intel_drv.h | 7 + > 3 files changed, 59 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 146609a..aee8258 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -3551,7 +3551,11 @@ enum punit_power_well { > /* New style CUR*CNTR flags */ > #define CURSOR_MODE0x27 > #define CURSOR_MODE_DISABLE 0x00 > +#define CURSOR_MODE_128_32B_AX 0x02 > +#define CURSOR_MODE_256_32B_AX 0x03 > #define CURSOR_MODE_64_32B_AX 0x07 > +#define CURSOR_MODE_128_ARGB_AX ((1 << 5) | CURSOR_MODE_128_32B_AX) > +#define CURSOR_MODE_256_ARGB_AX ((1 << 5) | CURSOR_MODE_256_32B_AX) > #define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) > #define MCURSOR_PIPE_SELECT(1 << 28) > #define MCURSOR_PIPE_A 0x00 > diff --git a/drivers/gpu/drm/i915/intel_display.c > b/drivers/gpu/drm/i915/intel_display.c > index 0868afb..ec6a073 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -7440,10 +7440,26 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, > u32 base) > bool visible = base != 0; > > if (intel_crtc->cursor_visible != visible) { > + int16_t width = intel_crtc->cursor_width; > uint32_t cntl = I915_READ(CURCNTR(pipe)); > if (base) { > cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); > - cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; > + cntl |= MCURSOR_GAMMA_ENABLE; > + > + switch (width) { > + case 64: > + cntl |= CURSOR_MODE_64_ARGB_AX; > + break; > + case 128: > + cntl |= CURSOR_MODE_128_ARGB_AX; > + break; > + case 256: > + cntl |= CURSOR_MODE_256_ARGB_AX; > + break; > + default: > + WARN_ON(1); > + return; > + } > cntl |= pipe << 28; /* Connect to correct pipe */ > } else { > cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); > @@ -7468,10 +7484,25 @@ static void ivb_update_cursor(struct drm_crtc *crtc, > u32 base) > bool visible = base != 0; > > if (intel_crtc->cursor_visible != visible) { > + int16_t width = intel_crtc->cursor_width; > uint32_t cntl = I915_READ(CURCNTR_IVB(pipe)); > if (base) { > cntl &= ~CURSOR_MODE; > - cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; > + cntl |= MCURSOR_GAMMA_ENABLE; > + switch (width) { > + case 64: > + cntl |= CURSOR_MODE_64_ARGB_AX; > + break; > + case 128: > + cntl |= CURSOR_MODE_128_ARGB_AX; > + break; > + case 256: > + cntl |= CURSOR_MODE_256_ARGB_AX; > + break; > + default: > + WARN_ON(1); > + return; > + } > } else { > cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); > cntl |= CURSOR_MODE_DISABLE; > @@ -7567,9 +7598,11 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, > goto finish; > } > > - /* Currently we only support 64x64 cursors */ > - if (width != 64 || height != 64) { > - DRM_ERROR("we currently only support 64x64 cursors\n"); > + /* Check for which cursor types we support */ > + if (!((width == 64 && height == 64) || > + (width == 128 && height == 128
Re: [PATCH v4 1/1] drm/i915: Enabling 128x128 and 256x256 ARGB Cursor Support
Gentle reminder for reviewing this and i-g-t patch. On Mon, 2014-03-10 at 17:06 +0530, sagar.a.kam...@intel.com wrote: From: Sagar Kamble sagar.a.kam...@intel.com With this patch we allow larger cursor planes of sizes 128x128 and 256x256. v2: Added more precise check on size while setting cursor plane. v3: Changes related to restructuring cursor size restrictions and DRM_DEBUG usage. v4: Indentation related changes for setting cursor control and implementing DRM_CAP_CURSOR_WIDTH and DRM_CAP_CURSOR_HEIGHT Testcase: igt/kms_cursor_crc Cc: Daniel Vetter daniel.vet...@ffwll.ch Cc: Jani Nikula jani.nik...@linux.intel.com Cc: David Airlie airl...@linux.ie Cc: dri-de...@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Signed-off-by: G, Pallavi pallav...@intel.com Signed-off-by: Sagar Kamble sagar.a.kam...@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 4 +++ drivers/gpu/drm/i915/intel_display.c | 53 drivers/gpu/drm/i915/intel_drv.h | 7 + 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 146609a..aee8258 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3551,7 +3551,11 @@ enum punit_power_well { /* New style CUR*CNTR flags */ #define CURSOR_MODE0x27 #define CURSOR_MODE_DISABLE 0x00 +#define CURSOR_MODE_128_32B_AX 0x02 +#define CURSOR_MODE_256_32B_AX 0x03 #define CURSOR_MODE_64_32B_AX 0x07 +#define CURSOR_MODE_128_ARGB_AX ((1 5) | CURSOR_MODE_128_32B_AX) +#define CURSOR_MODE_256_ARGB_AX ((1 5) | CURSOR_MODE_256_32B_AX) #define CURSOR_MODE_64_ARGB_AX ((1 5) | CURSOR_MODE_64_32B_AX) #define MCURSOR_PIPE_SELECT(1 28) #define MCURSOR_PIPE_A 0x00 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0868afb..ec6a073 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7440,10 +7440,26 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) bool visible = base != 0; if (intel_crtc-cursor_visible != visible) { + int16_t width = intel_crtc-cursor_width; uint32_t cntl = I915_READ(CURCNTR(pipe)); if (base) { cntl = ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); - cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + cntl |= MCURSOR_GAMMA_ENABLE; + + switch (width) { + case 64: + cntl |= CURSOR_MODE_64_ARGB_AX; + break; + case 128: + cntl |= CURSOR_MODE_128_ARGB_AX; + break; + case 256: + cntl |= CURSOR_MODE_256_ARGB_AX; + break; + default: + WARN_ON(1); + return; + } cntl |= pipe 28; /* Connect to correct pipe */ } else { cntl = ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); @@ -7468,10 +7484,25 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) bool visible = base != 0; if (intel_crtc-cursor_visible != visible) { + int16_t width = intel_crtc-cursor_width; uint32_t cntl = I915_READ(CURCNTR_IVB(pipe)); if (base) { cntl = ~CURSOR_MODE; - cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + cntl |= MCURSOR_GAMMA_ENABLE; + switch (width) { + case 64: + cntl |= CURSOR_MODE_64_ARGB_AX; + break; + case 128: + cntl |= CURSOR_MODE_128_ARGB_AX; + break; + case 256: + cntl |= CURSOR_MODE_256_ARGB_AX; + break; + default: + WARN_ON(1); + return; + } } else { cntl = ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); cntl |= CURSOR_MODE_DISABLE; @@ -7567,9 +7598,11 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, goto finish; } - /* Currently we only support 64x64 cursors */ - if (width != 64 || height != 64) { - DRM_ERROR(we currently only support 64x64 cursors\n); + /* Check for which cursor types we support */ + if (!((width == 64 height == 64) || + (width == 128 height == 128
Re: [PATCH v3 1/1] drm/i915: Enabling 128x128 and 256x256 ARGB Cursor Support
On Sun, 2014-03-09 at 00:34 +0530, Sagar Arun Kamble wrote: > On Sat, 2014-03-08 at 13:51 -0500, Alex Deucher wrote: > > On Sat, Mar 8, 2014 at 1:49 PM, wrote: > > > From: Sagar Kamble > > > > > > With this patch we allow larger cursor planes of sizes 128x128 > > > and 256x256. > > > > > > v2: Added more precise check on size while setting cursor plane. > > > > > > v3: Changes related to restructuring cursor size restrictions > > > and DRM_DEBUG usage. > > > > > > > I'm not sure how useful it is since you appear to be able to > > selectively adjust the cursor size, but I recently added support for > > exposing the cursor size as a drm cap: > > http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8716ed4e7bed4e4c7e3f37940e950ddc0362f450 > > > > Alex > Thanks Alex. This is useful for cursor test to enumerate sub-tests based > on these caps. Realized after sending mail that we just get to know current cursor width and height. Can we have capability that exposes all supported cursor sizes? > > > > > Testcase: igt/kms_cursor_crc > > > Cc: Daniel Vetter > > > Cc: Jani Nikula > > > Cc: David Airlie > > > Cc: dri-de...@lists.freedesktop.org > > > Cc: linux-kernel@vger.kernel.org > > > Signed-off-by: G, Pallavi > > > Signed-off-by: Sagar Kamble > > > --- > > > drivers/gpu/drm/i915/i915_reg.h | 4 > > > drivers/gpu/drm/i915/intel_display.c | 36 > > > +++- > > > 2 files changed, 35 insertions(+), 5 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/i915/i915_reg.h > > > b/drivers/gpu/drm/i915/i915_reg.h > > > index 146609a..aee8258 100644 > > > --- a/drivers/gpu/drm/i915/i915_reg.h > > > +++ b/drivers/gpu/drm/i915/i915_reg.h > > > @@ -3551,7 +3551,11 @@ enum punit_power_well { > > > /* New style CUR*CNTR flags */ > > > #define CURSOR_MODE 0x27 > > > #define CURSOR_MODE_DISABLE 0x00 > > > +#define CURSOR_MODE_128_32B_AX 0x02 > > > +#define CURSOR_MODE_256_32B_AX 0x03 > > > #define CURSOR_MODE_64_32B_AX 0x07 > > > +#define CURSOR_MODE_128_ARGB_AX ((1 << 5) | CURSOR_MODE_128_32B_AX) > > > +#define CURSOR_MODE_256_ARGB_AX ((1 << 5) | CURSOR_MODE_256_32B_AX) > > > #define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) > > > #define MCURSOR_PIPE_SELECT (1 << 28) > > > #define MCURSOR_PIPE_A 0x00 > > > diff --git a/drivers/gpu/drm/i915/intel_display.c > > > b/drivers/gpu/drm/i915/intel_display.c > > > index 0868afb..e59e8fd 100644 > > > --- a/drivers/gpu/drm/i915/intel_display.c > > > +++ b/drivers/gpu/drm/i915/intel_display.c > > > @@ -7440,10 +7440,22 @@ static void i9xx_update_cursor(struct drm_crtc > > > *crtc, u32 base) > > > bool visible = base != 0; > > > > > > if (intel_crtc->cursor_visible != visible) { > > > + int16_t width = intel_crtc->cursor_width; > > > uint32_t cntl = I915_READ(CURCNTR(pipe)); > > > if (base) { > > > cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); > > > - cntl |= CURSOR_MODE_64_ARGB_AX | > > > MCURSOR_GAMMA_ENABLE; > > > + > > > + switch (width) { > > > + case 64: > > > + cntl |= CURSOR_MODE_64_ARGB_AX | > > > MCURSOR_GAMMA_ENABLE; > > > + break; > > > + case 128: > > > + cntl |= CURSOR_MODE_128_ARGB_AX | > > > MCURSOR_GAMMA_ENABLE; > > > + break; > > > + case 256: > > > + cntl |= CURSOR_MODE_256_ARGB_AX | > > > MCURSOR_GAMMA_ENABLE; > > > + break; > > > + } > > > cntl |= pipe << 28; /* Connect to correct pipe */ > > > } else { > > > cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); > > > @@ -7468,10 +7480,22 @@ static void ivb_update_cursor(struct drm_crtc > > > *crtc, u32 base) > > > bool visib
Re: [PATCH v3 1/1] drm/i915: Enabling 128x128 and 256x256 ARGB Cursor Support
On Sat, 2014-03-08 at 13:51 -0500, Alex Deucher wrote: > On Sat, Mar 8, 2014 at 1:49 PM, wrote: > > From: Sagar Kamble > > > > With this patch we allow larger cursor planes of sizes 128x128 > > and 256x256. > > > > v2: Added more precise check on size while setting cursor plane. > > > > v3: Changes related to restructuring cursor size restrictions > > and DRM_DEBUG usage. > > > > I'm not sure how useful it is since you appear to be able to > selectively adjust the cursor size, but I recently added support for > exposing the cursor size as a drm cap: > http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8716ed4e7bed4e4c7e3f37940e950ddc0362f450 > > Alex Thanks Alex. This is useful for cursor test to enumerate sub-tests based on these caps. > > > Testcase: igt/kms_cursor_crc > > Cc: Daniel Vetter > > Cc: Jani Nikula > > Cc: David Airlie > > Cc: dri-de...@lists.freedesktop.org > > Cc: linux-kernel@vger.kernel.org > > Signed-off-by: G, Pallavi > > Signed-off-by: Sagar Kamble > > --- > > drivers/gpu/drm/i915/i915_reg.h | 4 > > drivers/gpu/drm/i915/intel_display.c | 36 > > +++- > > 2 files changed, 35 insertions(+), 5 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/i915_reg.h > > b/drivers/gpu/drm/i915/i915_reg.h > > index 146609a..aee8258 100644 > > --- a/drivers/gpu/drm/i915/i915_reg.h > > +++ b/drivers/gpu/drm/i915/i915_reg.h > > @@ -3551,7 +3551,11 @@ enum punit_power_well { > > /* New style CUR*CNTR flags */ > > #define CURSOR_MODE 0x27 > > #define CURSOR_MODE_DISABLE 0x00 > > +#define CURSOR_MODE_128_32B_AX 0x02 > > +#define CURSOR_MODE_256_32B_AX 0x03 > > #define CURSOR_MODE_64_32B_AX 0x07 > > +#define CURSOR_MODE_128_ARGB_AX ((1 << 5) | CURSOR_MODE_128_32B_AX) > > +#define CURSOR_MODE_256_ARGB_AX ((1 << 5) | CURSOR_MODE_256_32B_AX) > > #define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX) > > #define MCURSOR_PIPE_SELECT (1 << 28) > > #define MCURSOR_PIPE_A 0x00 > > diff --git a/drivers/gpu/drm/i915/intel_display.c > > b/drivers/gpu/drm/i915/intel_display.c > > index 0868afb..e59e8fd 100644 > > --- a/drivers/gpu/drm/i915/intel_display.c > > +++ b/drivers/gpu/drm/i915/intel_display.c > > @@ -7440,10 +7440,22 @@ static void i9xx_update_cursor(struct drm_crtc > > *crtc, u32 base) > > bool visible = base != 0; > > > > if (intel_crtc->cursor_visible != visible) { > > + int16_t width = intel_crtc->cursor_width; > > uint32_t cntl = I915_READ(CURCNTR(pipe)); > > if (base) { > > cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); > > - cntl |= CURSOR_MODE_64_ARGB_AX | > > MCURSOR_GAMMA_ENABLE; > > + > > + switch (width) { > > + case 64: > > + cntl |= CURSOR_MODE_64_ARGB_AX | > > MCURSOR_GAMMA_ENABLE; > > + break; > > + case 128: > > + cntl |= CURSOR_MODE_128_ARGB_AX | > > MCURSOR_GAMMA_ENABLE; > > + break; > > + case 256: > > + cntl |= CURSOR_MODE_256_ARGB_AX | > > MCURSOR_GAMMA_ENABLE; > > + break; > > + } > > cntl |= pipe << 28; /* Connect to correct pipe */ > > } else { > > cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); > > @@ -7468,10 +7480,22 @@ static void ivb_update_cursor(struct drm_crtc > > *crtc, u32 base) > > bool visible = base != 0; > > > > if (intel_crtc->cursor_visible != visible) { > > + int16_t width = intel_crtc->cursor_width; > > uint32_t cntl = I915_READ(CURCNTR_IVB(pipe)); > > if (base) { > > cntl &= ~CURSOR_MODE; > > - cntl |= CURSOR_MODE_64_ARGB_AX | > > MCURSOR_GAMMA_ENABLE; > > + > > + switch (width) { > > + case 64: > > + cntl |= CURSOR_MODE_64_ARGB_AX | > > MCURSOR_GAMMA_ENABLE; > > + break; > > + case 128: > > + cntl |= CURSOR_MODE_128_ARGB_AX | > > MCURSOR_GAMMA_ENABLE; > > + break; > > + case 256: > > + cntl |= CURSOR_MODE_256_ARGB_AX | > > MCURSOR_GAMMA_ENABLE; > > + break; > > + } > > } else { > > cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); > > cntl |= CURSOR_MODE_DISABLE; > > @@
Re: [PATCH v3 1/1] drm/i915: Enabling 128x128 and 256x256 ARGB Cursor Support
On Sat, 2014-03-08 at 13:51 -0500, Alex Deucher wrote: On Sat, Mar 8, 2014 at 1:49 PM, sagar.a.kam...@intel.com wrote: From: Sagar Kamble sagar.a.kam...@intel.com With this patch we allow larger cursor planes of sizes 128x128 and 256x256. v2: Added more precise check on size while setting cursor plane. v3: Changes related to restructuring cursor size restrictions and DRM_DEBUG usage. I'm not sure how useful it is since you appear to be able to selectively adjust the cursor size, but I recently added support for exposing the cursor size as a drm cap: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8716ed4e7bed4e4c7e3f37940e950ddc0362f450 Alex Thanks Alex. This is useful for cursor test to enumerate sub-tests based on these caps. Testcase: igt/kms_cursor_crc Cc: Daniel Vetter daniel.vet...@ffwll.ch Cc: Jani Nikula jani.nik...@linux.intel.com Cc: David Airlie airl...@linux.ie Cc: dri-de...@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Signed-off-by: G, Pallavi pallav...@intel.com Signed-off-by: Sagar Kamble sagar.a.kam...@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 4 drivers/gpu/drm/i915/intel_display.c | 36 +++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 146609a..aee8258 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3551,7 +3551,11 @@ enum punit_power_well { /* New style CUR*CNTR flags */ #define CURSOR_MODE 0x27 #define CURSOR_MODE_DISABLE 0x00 +#define CURSOR_MODE_128_32B_AX 0x02 +#define CURSOR_MODE_256_32B_AX 0x03 #define CURSOR_MODE_64_32B_AX 0x07 +#define CURSOR_MODE_128_ARGB_AX ((1 5) | CURSOR_MODE_128_32B_AX) +#define CURSOR_MODE_256_ARGB_AX ((1 5) | CURSOR_MODE_256_32B_AX) #define CURSOR_MODE_64_ARGB_AX ((1 5) | CURSOR_MODE_64_32B_AX) #define MCURSOR_PIPE_SELECT (1 28) #define MCURSOR_PIPE_A 0x00 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0868afb..e59e8fd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7440,10 +7440,22 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) bool visible = base != 0; if (intel_crtc-cursor_visible != visible) { + int16_t width = intel_crtc-cursor_width; uint32_t cntl = I915_READ(CURCNTR(pipe)); if (base) { cntl = ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); - cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + + switch (width) { + case 64: + cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + break; + case 128: + cntl |= CURSOR_MODE_128_ARGB_AX | MCURSOR_GAMMA_ENABLE; + break; + case 256: + cntl |= CURSOR_MODE_256_ARGB_AX | MCURSOR_GAMMA_ENABLE; + break; + } cntl |= pipe 28; /* Connect to correct pipe */ } else { cntl = ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); @@ -7468,10 +7480,22 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) bool visible = base != 0; if (intel_crtc-cursor_visible != visible) { + int16_t width = intel_crtc-cursor_width; uint32_t cntl = I915_READ(CURCNTR_IVB(pipe)); if (base) { cntl = ~CURSOR_MODE; - cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + + switch (width) { + case 64: + cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + break; + case 128: + cntl |= CURSOR_MODE_128_ARGB_AX | MCURSOR_GAMMA_ENABLE; + break; + case 256: + cntl |= CURSOR_MODE_256_ARGB_AX | MCURSOR_GAMMA_ENABLE; + break; + } } else { cntl = ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); cntl |= CURSOR_MODE_DISABLE; @@ -7567,9 +7591,11 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
Re: [PATCH v3 1/1] drm/i915: Enabling 128x128 and 256x256 ARGB Cursor Support
On Sun, 2014-03-09 at 00:34 +0530, Sagar Arun Kamble wrote: On Sat, 2014-03-08 at 13:51 -0500, Alex Deucher wrote: On Sat, Mar 8, 2014 at 1:49 PM, sagar.a.kam...@intel.com wrote: From: Sagar Kamble sagar.a.kam...@intel.com With this patch we allow larger cursor planes of sizes 128x128 and 256x256. v2: Added more precise check on size while setting cursor plane. v3: Changes related to restructuring cursor size restrictions and DRM_DEBUG usage. I'm not sure how useful it is since you appear to be able to selectively adjust the cursor size, but I recently added support for exposing the cursor size as a drm cap: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8716ed4e7bed4e4c7e3f37940e950ddc0362f450 Alex Thanks Alex. This is useful for cursor test to enumerate sub-tests based on these caps. Realized after sending mail that we just get to know current cursor width and height. Can we have capability that exposes all supported cursor sizes? Testcase: igt/kms_cursor_crc Cc: Daniel Vetter daniel.vet...@ffwll.ch Cc: Jani Nikula jani.nik...@linux.intel.com Cc: David Airlie airl...@linux.ie Cc: dri-de...@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Signed-off-by: G, Pallavi pallav...@intel.com Signed-off-by: Sagar Kamble sagar.a.kam...@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 4 drivers/gpu/drm/i915/intel_display.c | 36 +++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 146609a..aee8258 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3551,7 +3551,11 @@ enum punit_power_well { /* New style CUR*CNTR flags */ #define CURSOR_MODE 0x27 #define CURSOR_MODE_DISABLE 0x00 +#define CURSOR_MODE_128_32B_AX 0x02 +#define CURSOR_MODE_256_32B_AX 0x03 #define CURSOR_MODE_64_32B_AX 0x07 +#define CURSOR_MODE_128_ARGB_AX ((1 5) | CURSOR_MODE_128_32B_AX) +#define CURSOR_MODE_256_ARGB_AX ((1 5) | CURSOR_MODE_256_32B_AX) #define CURSOR_MODE_64_ARGB_AX ((1 5) | CURSOR_MODE_64_32B_AX) #define MCURSOR_PIPE_SELECT (1 28) #define MCURSOR_PIPE_A 0x00 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0868afb..e59e8fd 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7440,10 +7440,22 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) bool visible = base != 0; if (intel_crtc-cursor_visible != visible) { + int16_t width = intel_crtc-cursor_width; uint32_t cntl = I915_READ(CURCNTR(pipe)); if (base) { cntl = ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); - cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + + switch (width) { + case 64: + cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + break; + case 128: + cntl |= CURSOR_MODE_128_ARGB_AX | MCURSOR_GAMMA_ENABLE; + break; + case 256: + cntl |= CURSOR_MODE_256_ARGB_AX | MCURSOR_GAMMA_ENABLE; + break; + } cntl |= pipe 28; /* Connect to correct pipe */ } else { cntl = ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); @@ -7468,10 +7480,22 @@ static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) bool visible = base != 0; if (intel_crtc-cursor_visible != visible) { + int16_t width = intel_crtc-cursor_width; uint32_t cntl = I915_READ(CURCNTR_IVB(pipe)); if (base) { cntl = ~CURSOR_MODE; - cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + + switch (width) { + case 64: + cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + break; + case 128: + cntl |= CURSOR_MODE_128_ARGB_AX | MCURSOR_GAMMA_ENABLE; + break; + case 256: + cntl |= CURSOR_MODE_256_ARGB_AX | MCURSOR_GAMMA_ENABLE
Re: [Intel-gfx] [PATCH v5 11/11] drm/i915: Calling rotate and inverse rotate transformations after clipping
On Tue, 2014-02-11 at 16:56 +0200, Ville Syrjälä wrote: > On Tue, Feb 11, 2014 at 05:02:31PM +0530, Sagar Arun Kamble wrote: > > On Mon, 2014-02-10 at 15:32 +0200, Ville Syrjälä wrote: > > > On Mon, Feb 10, 2014 at 01:01:18PM +0530, sagar.a.kam...@intel.com wrote: > > > > From: Sagar Kamble > > > > > > > > With clipped sprites these transformations are not working. these > > > > functions transform complete sprite irrespective of clipping present. > > > > This leads to invisible portion of sprite show up when rotate 180 if > > > > it was out of visible area before. > > > > > > > > v4: Moved rotate transform for source rectangle after clipping. > > > > Added rotate and inverse rotate transform for destination rect. > > > > > > Still NAK. > > > > > > I just pushed rotation support to my glplane test app [1], and with > > > with that my rotated clipping code works exactly as intended. > > > > > > [1] git://gitorious.org/vsyrjala/glplane.git > > I tried this app. I think I am considering 180 degree rotation of > > clipped sprite plane differently. I have captured output with these > > rotate transforms moved before(clip-rotated) and after(rotate-clipped) > > clipping code. > > > > Which is valid? Rotating entire sprite and then clipping or Rotating > > clipped portion? > > > > Reference and Rotated output is attached FYI. > > > > If rotating entire sprite is correct then this patch 11/11 is not needed > > and can be abandoned. > > The way I think of these things is roughly this: > > You have the user specified source rectangle, where the coordinates specify > the viewport into the framebuffer. This coordinate space is oriented the > same was as the framebuffer itself, ie. the first pixel of the > framebuffer is at coordinates 0,0. So plane rotation doesn't affect this > at all. > > Then you have the user specified destination/crtc rectangle, where the > coordinates specify the position of the plane within the crtc coordinate > space. So the first visible pixel the pipe will push out is at > coordinates 0,0. So again plane rotation doesn't affect this. > > Then you have the rotation which simply specifies the transformation to > be applied to the pixels when they "move" from the source rectangle to > the destination rectangle. So w/ 0 degree rotation the pixel at > src_x,src_y in the framebuffer will appear at position crtc_x,crtc_y > on the crtc output. With 180 degree rotation the pixel at src_x,src_y > will appear at crtc_x+crtc_w-1,crtc_y+crtc_h-1. > > As clipping happens in the crtc coordinate space, we need to orient > the source coordindates the same way to get the correct clipping result. > So for example with 0 degrees rotation clipping the left side of the > destination rectangle must result in clipping the left side of the source > rectangle as well. And with 180 degree rotation clipping the destination > rectangle on the left side must result in clipping the source rectangle > on the right side. Left and right in each case referring to the original > unrotate coordinates. > > So let's say we have the following situation w/ 180 degree rotation. > The letters inside the rects represented specific named pixels, > the FB rectangle represents the FB as specified by addfb2 ioctl, > the CRTC rectangle represents the pipe output (0,0 -> PIPESRC.w,h): > > FB: CRTC: > 0,0 ___ 0.0 __ > | abcd | | | > | efgh | | | > |_| |hgfe | > |dcba_| > unclipped coordinates specified by user: > src_x=2,src_y=0 crtc_x=0,crtc_y=2 > src_w=4.src_h=2 crtc_w=4,crtc_h=2 > > clipped coordinates: > src_x=2,src_y=0 crtc_x=0,crtc_y=2 > src_w=4.src_h=2 crtc_w=4,crtc_h=2 > > > Then the user moves the sprite one pixel to the left resulting on some > clipping (the X pixels). Note that the unclipped source coordinates do > not change here at all, in fact crtc_x is the only thing changed by the > user: > > FB: CRTC: > 0,0 ___ 0.0 __ > | abcX | | | > | efgX | | | > |_| Xgfe | > Xcba__| > unclipped coordinates specified by user: > src_x=2,src_y=0 crtc_x=-1,crtc_y=2 > src_w=4.src_h=2 crtc_w= 4,crtc_h=2 > > clipped coordinates: > src_x=2,src_y=0 crtc_x=0,crtc_y=2 > src_w=3.src_h=2 crtc_w=3,crtc_h=2 > Understood this now. Thank you Ville for providing this elaborate graphical view of the rotation cases. -Sagar -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Intel-gfx] [PATCH v5 11/11] drm/i915: Calling rotate and inverse rotate transformations after clipping
On Tue, 2014-02-11 at 12:59 +0100, Daniel Vetter wrote: > On Tue, Feb 11, 2014 at 05:02:31PM +0530, Sagar Arun Kamble wrote: > > On Mon, 2014-02-10 at 15:32 +0200, Ville Syrjälä wrote: > > > On Mon, Feb 10, 2014 at 01:01:18PM +0530, sagar.a.kam...@intel.com wrote: > > > > From: Sagar Kamble > > > > > > > > With clipped sprites these transformations are not working. these > > > > functions transform complete sprite irrespective of clipping present. > > > > This leads to invisible portion of sprite show up when rotate 180 if > > > > it was out of visible area before. > > > > > > > > v4: Moved rotate transform for source rectangle after clipping. > > > > Added rotate and inverse rotate transform for destination rect. > > > > > > Still NAK. > > > > > > I just pushed rotation support to my glplane test app [1], and with > > > with that my rotated clipping code works exactly as intended. > > > > > > [1] git://gitorious.org/vsyrjala/glplane.git > > I tried this app. I think I am considering 180 degree rotation of > > clipped sprite plane differently. I have captured output with these > > rotate transforms moved before(clip-rotated) and after(rotate-clipped) > > clipping code. > > > > Which is valid? Rotating entire sprite and then clipping or Rotating > > clipped portion? > > > > Reference and Rotated output is attached FYI. > > > > If rotating entire sprite is correct then this patch 11/11 is not needed > > and can be abandoned. > > I think doing the clipping first (as a viewport) and then rotating the > viewport makes more sense to me. Dunno what other people think, but I > guess we should document that somewhere. > -Daniel Agree. Thought of use-case where if media player(that will use sprite for video) is moved such that it is off the screen partially, after rotation as well we should see same portion of clip inside(rotated though). > > > > > thanks, > > Sagar > > > > > > > > Cc: Daniel Vetter > > > > Cc: Jani Nikula > > > > Cc: David Airlie > > > > Cc: dri-de...@lists.freedesktop.org > > > > Cc: linux-kernel@vger.kernel.org > > > > Cc: vijay.a.purushotha...@intel.com > > > > Signed-off-by: Sagar Kamble > > > > --- > > > > drivers/gpu/drm/i915/intel_sprite.c | 16 > > > > 1 file changed, 12 insertions(+), 4 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/i915/intel_sprite.c > > > > b/drivers/gpu/drm/i915/intel_sprite.c > > > > index 62b9f84..799f6a9 100644 > > > > --- a/drivers/gpu/drm/i915/intel_sprite.c > > > > +++ b/drivers/gpu/drm/i915/intel_sprite.c > > > > @@ -769,9 +769,6 @@ intel_update_plane(struct drm_plane *plane, struct > > > > drm_crtc *crtc, > > > > max_scale = intel_plane->max_downscale << 16; > > > > min_scale = intel_plane->can_scale ? 1 : (1 << 16); > > > > > > > > - drm_rect_rotate(, fb->width << 16, fb->height << 16, > > > > - intel_plane->rotation); > > > > - > > > > hscale = drm_rect_calc_hscale_relaxed(, , min_scale, > > > > max_scale); > > > > BUG_ON(hscale < 0); > > > > > > > > @@ -785,6 +782,13 @@ intel_update_plane(struct drm_plane *plane, struct > > > > drm_crtc *crtc, > > > > crtc_w = drm_rect_width(); > > > > crtc_h = drm_rect_height(); > > > > > > > > + drm_rect_rotate(, fb->width << 16, fb->height << 16, > > > > + intel_plane->rotation); > > > > + > > > > + drm_rect_rotate(, intel_crtc->config.pipe_src_w, > > > > + intel_crtc->config.pipe_src_h, > > > > + intel_plane->rotation); > > > > + > > > > if (visible) { > > > > /* check again in case clipping clamped the results */ > > > > hscale = drm_rect_calc_hscale(, , min_scale, > > > > max_scale); > > > > @@ -811,7 +815,11 @@ intel_update_plane(struct drm_plane *plane, struct > > > > drm_crtc *crtc, > > > > drm_rect_height() * vscale - > > > > drm_rect_height()); > > > &
Re: [PATCH v2 02/11] drm: Add support_bits parameter to drm_property_create_bitmask()
Reviewed-by: Sagar Kamble Tested-by: Sagar Kamble On Mon, 2014-02-10 at 16:05 +0200, ville.syrj...@linux.intel.com wrote: > From: Ville Syrjälä > > Make drm_property_create_bitmask() a bit more generic by allowing the > caller to specify which bits are in fact supported. This allows multiple > callers to use the same enum list, but still create different versions > of the same property with different list of supported bits. > > v2: Populate values[] array as non-sparse > Make supported_bits 64bit > Fix up omapdrm call site (Rob) > > Cc: Tomi Valkeinen > Cc: Rob Clark > Cc: Sagar Kamble > Cc: dri-de...@lists.freedesktop.org > Signed-off-by: Ville Syrjälä > --- > This should also make my original "drm: Add > drm_mode_create_rotation_property()" > patch do the right thing. So patch 03/11 of the series needs to be replaced > with the > original. > > drivers/gpu/drm/drm_crtc.c | 18 ++ > drivers/gpu/drm/omapdrm/omap_plane.c | 5 - > include/drm/drm_crtc.h | 3 ++- > 3 files changed, 20 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c > index 3b7d32d..6e099069 100644 > --- a/drivers/gpu/drm/drm_crtc.c > +++ b/drivers/gpu/drm/drm_crtc.c > @@ -2906,10 +2906,12 @@ EXPORT_SYMBOL(drm_property_create_enum); > struct drm_property *drm_property_create_bitmask(struct drm_device *dev, >int flags, const char *name, >const struct drm_prop_enum_list *props, > - int num_values) > + int num_props, > + uint64_t supported_bits) > { > struct drm_property *property; > - int i, ret; > + int i, ret, index = 0; > + int num_values = hweight64(supported_bits); > > flags |= DRM_MODE_PROP_BITMASK; > > @@ -2917,8 +2919,16 @@ struct drm_property > *drm_property_create_bitmask(struct drm_device *dev, > if (!property) > return NULL; > > - for (i = 0; i < num_values; i++) { > - ret = drm_property_add_enum(property, i, > + for (i = 0; i < num_props; i++) { > + if (!(supported_bits & (1ULL << props[i].type))) > + continue; > + > + if (WARN_ON(index >= num_values)) { > + drm_property_destroy(dev, property); > + return NULL; > + } > + > + ret = drm_property_add_enum(property, index++, > props[i].type, > props[i].name); > if (ret) { > diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c > b/drivers/gpu/drm/omapdrm/omap_plane.c > index 046d5e6..0d97650 100644 > --- a/drivers/gpu/drm/omapdrm/omap_plane.c > +++ b/drivers/gpu/drm/omapdrm/omap_plane.c > @@ -309,7 +309,10 @@ void omap_plane_install_properties(struct drm_plane > *plane, > { DRM_REFLECT_Y, "reflect-y" }, > }; > prop = drm_property_create_bitmask(dev, 0, "rotation", > - props, ARRAY_SIZE(props)); > + props, ARRAY_SIZE(props), > + BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_90) | > + BIT(DRM_ROTATE_180) | > BIT(DRM_ROTATE_270) | > + BIT(DRM_REFLECT_X) | > BIT(DRM_REFLECT_Y)); > if (prop == NULL) > return; > priv->rotation_prop = prop; > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h > index d5c46c1..4e6d2aa 100644 > --- a/include/drm/drm_crtc.h > +++ b/include/drm/drm_crtc.h > @@ -1070,7 +1070,8 @@ extern struct drm_property > *drm_property_create_enum(struct drm_device *dev, int > struct drm_property *drm_property_create_bitmask(struct drm_device *dev, >int flags, const char *name, >const struct drm_prop_enum_list *props, > - int num_values); > + int num_props, > + uint64_t supported_bits); > struct drm_property *drm_property_create_range(struct drm_device *dev, int > flags, >const char *name, >uint64_t min, uint64_t max); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 02/11] drm: Add support_bits parameter to drm_property_create_bitmask()
Reviewed-by: Sagar Kamble sagar.a.kam...@intel.com Tested-by: Sagar Kamble sagar.a.kam...@intel.com On Mon, 2014-02-10 at 16:05 +0200, ville.syrj...@linux.intel.com wrote: From: Ville Syrjälä ville.syrjala at linux.intel.com Make drm_property_create_bitmask() a bit more generic by allowing the caller to specify which bits are in fact supported. This allows multiple callers to use the same enum list, but still create different versions of the same property with different list of supported bits. v2: Populate values[] array as non-sparse Make supported_bits 64bit Fix up omapdrm call site (Rob) Cc: Tomi Valkeinen tomi.valkei...@ti.com Cc: Rob Clark robdcl...@gmail.com Cc: Sagar Kamble sagar.a.kam...@intel.com Cc: dri-de...@lists.freedesktop.org Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com --- This should also make my original drm: Add drm_mode_create_rotation_property() patch do the right thing. So patch 03/11 of the series needs to be replaced with the original. drivers/gpu/drm/drm_crtc.c | 18 ++ drivers/gpu/drm/omapdrm/omap_plane.c | 5 - include/drm/drm_crtc.h | 3 ++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 3b7d32d..6e099069 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2906,10 +2906,12 @@ EXPORT_SYMBOL(drm_property_create_enum); struct drm_property *drm_property_create_bitmask(struct drm_device *dev, int flags, const char *name, const struct drm_prop_enum_list *props, - int num_values) + int num_props, + uint64_t supported_bits) { struct drm_property *property; - int i, ret; + int i, ret, index = 0; + int num_values = hweight64(supported_bits); flags |= DRM_MODE_PROP_BITMASK; @@ -2917,8 +2919,16 @@ struct drm_property *drm_property_create_bitmask(struct drm_device *dev, if (!property) return NULL; - for (i = 0; i num_values; i++) { - ret = drm_property_add_enum(property, i, + for (i = 0; i num_props; i++) { + if (!(supported_bits (1ULL props[i].type))) + continue; + + if (WARN_ON(index = num_values)) { + drm_property_destroy(dev, property); + return NULL; + } + + ret = drm_property_add_enum(property, index++, props[i].type, props[i].name); if (ret) { diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index 046d5e6..0d97650 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -309,7 +309,10 @@ void omap_plane_install_properties(struct drm_plane *plane, { DRM_REFLECT_Y, reflect-y }, }; prop = drm_property_create_bitmask(dev, 0, rotation, - props, ARRAY_SIZE(props)); + props, ARRAY_SIZE(props), + BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_90) | + BIT(DRM_ROTATE_180) | BIT(DRM_ROTATE_270) | + BIT(DRM_REFLECT_X) | BIT(DRM_REFLECT_Y)); if (prop == NULL) return; priv-rotation_prop = prop; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index d5c46c1..4e6d2aa 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1070,7 +1070,8 @@ extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int struct drm_property *drm_property_create_bitmask(struct drm_device *dev, int flags, const char *name, const struct drm_prop_enum_list *props, - int num_values); + int num_props, + uint64_t supported_bits); struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, const char *name, uint64_t min, uint64_t max); -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Intel-gfx] [PATCH v5 11/11] drm/i915: Calling rotate and inverse rotate transformations after clipping
On Tue, 2014-02-11 at 12:59 +0100, Daniel Vetter wrote: On Tue, Feb 11, 2014 at 05:02:31PM +0530, Sagar Arun Kamble wrote: On Mon, 2014-02-10 at 15:32 +0200, Ville Syrjälä wrote: On Mon, Feb 10, 2014 at 01:01:18PM +0530, sagar.a.kam...@intel.com wrote: From: Sagar Kamble sagar.a.kam...@intel.com With clipped sprites these transformations are not working. these functions transform complete sprite irrespective of clipping present. This leads to invisible portion of sprite show up when rotate 180 if it was out of visible area before. v4: Moved rotate transform for source rectangle after clipping. Added rotate and inverse rotate transform for destination rect. Still NAK. I just pushed rotation support to my glplane test app [1], and with with that my rotated clipping code works exactly as intended. [1] git://gitorious.org/vsyrjala/glplane.git I tried this app. I think I am considering 180 degree rotation of clipped sprite plane differently. I have captured output with these rotate transforms moved before(clip-rotated) and after(rotate-clipped) clipping code. Which is valid? Rotating entire sprite and then clipping or Rotating clipped portion? Reference and Rotated output is attached FYI. If rotating entire sprite is correct then this patch 11/11 is not needed and can be abandoned. I think doing the clipping first (as a viewport) and then rotating the viewport makes more sense to me. Dunno what other people think, but I guess we should document that somewhere. -Daniel Agree. Thought of use-case where if media player(that will use sprite for video) is moved such that it is off the screen partially, after rotation as well we should see same portion of clip inside(rotated though). thanks, Sagar Cc: Daniel Vetter daniel.vet...@ffwll.ch Cc: Jani Nikula jani.nik...@linux.intel.com Cc: David Airlie airl...@linux.ie Cc: dri-de...@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Cc: vijay.a.purushotha...@intel.com Signed-off-by: Sagar Kamble sagar.a.kam...@intel.com --- drivers/gpu/drm/i915/intel_sprite.c | 16 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 62b9f84..799f6a9 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -769,9 +769,6 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, max_scale = intel_plane-max_downscale 16; min_scale = intel_plane-can_scale ? 1 : (1 16); - drm_rect_rotate(src, fb-width 16, fb-height 16, - intel_plane-rotation); - hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale); BUG_ON(hscale 0); @@ -785,6 +782,13 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, crtc_w = drm_rect_width(dst); crtc_h = drm_rect_height(dst); + drm_rect_rotate(src, fb-width 16, fb-height 16, + intel_plane-rotation); + + drm_rect_rotate(dst, intel_crtc-config.pipe_src_w, + intel_crtc-config.pipe_src_h, + intel_plane-rotation); + if (visible) { /* check again in case clipping clamped the results */ hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); @@ -811,7 +815,11 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, drm_rect_height(dst) * vscale - drm_rect_height(src)); drm_rect_rotate_inv(src, fb-width 16, fb-height 16, - intel_plane-rotation); + intel_plane-rotation); + + drm_rect_rotate_inv(dst, intel_crtc-config.pipe_src_w, + intel_crtc-config.pipe_src_h, + intel_plane-rotation); /* sanity check to make sure the src viewport wasn't enlarged */ WARN_ON(src.x1 (int) src_x || -- 1.8.5 ___ Intel-gfx mailing list intel-...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Intel-gfx] [PATCH v5 11/11] drm/i915: Calling rotate and inverse rotate transformations after clipping
On Tue, 2014-02-11 at 16:56 +0200, Ville Syrjälä wrote: On Tue, Feb 11, 2014 at 05:02:31PM +0530, Sagar Arun Kamble wrote: On Mon, 2014-02-10 at 15:32 +0200, Ville Syrjälä wrote: On Mon, Feb 10, 2014 at 01:01:18PM +0530, sagar.a.kam...@intel.com wrote: From: Sagar Kamble sagar.a.kam...@intel.com With clipped sprites these transformations are not working. these functions transform complete sprite irrespective of clipping present. This leads to invisible portion of sprite show up when rotate 180 if it was out of visible area before. v4: Moved rotate transform for source rectangle after clipping. Added rotate and inverse rotate transform for destination rect. Still NAK. I just pushed rotation support to my glplane test app [1], and with with that my rotated clipping code works exactly as intended. [1] git://gitorious.org/vsyrjala/glplane.git I tried this app. I think I am considering 180 degree rotation of clipped sprite plane differently. I have captured output with these rotate transforms moved before(clip-rotated) and after(rotate-clipped) clipping code. Which is valid? Rotating entire sprite and then clipping or Rotating clipped portion? Reference and Rotated output is attached FYI. If rotating entire sprite is correct then this patch 11/11 is not needed and can be abandoned. The way I think of these things is roughly this: You have the user specified source rectangle, where the coordinates specify the viewport into the framebuffer. This coordinate space is oriented the same was as the framebuffer itself, ie. the first pixel of the framebuffer is at coordinates 0,0. So plane rotation doesn't affect this at all. Then you have the user specified destination/crtc rectangle, where the coordinates specify the position of the plane within the crtc coordinate space. So the first visible pixel the pipe will push out is at coordinates 0,0. So again plane rotation doesn't affect this. Then you have the rotation which simply specifies the transformation to be applied to the pixels when they move from the source rectangle to the destination rectangle. So w/ 0 degree rotation the pixel at src_x,src_y in the framebuffer will appear at position crtc_x,crtc_y on the crtc output. With 180 degree rotation the pixel at src_x,src_y will appear at crtc_x+crtc_w-1,crtc_y+crtc_h-1. As clipping happens in the crtc coordinate space, we need to orient the source coordindates the same way to get the correct clipping result. So for example with 0 degrees rotation clipping the left side of the destination rectangle must result in clipping the left side of the source rectangle as well. And with 180 degree rotation clipping the destination rectangle on the left side must result in clipping the source rectangle on the right side. Left and right in each case referring to the original unrotate coordinates. So let's say we have the following situation w/ 180 degree rotation. The letters inside the rects represented specific named pixels, the FB rectangle represents the FB as specified by addfb2 ioctl, the CRTC rectangle represents the pipe output (0,0 - PIPESRC.w,h): FB: CRTC: 0,0 ___ 0.0 __ | abcd | | | | efgh | | | |_| |hgfe | |dcba_| unclipped coordinates specified by user: src_x=2,src_y=0 crtc_x=0,crtc_y=2 src_w=4.src_h=2 crtc_w=4,crtc_h=2 clipped coordinates: src_x=2,src_y=0 crtc_x=0,crtc_y=2 src_w=4.src_h=2 crtc_w=4,crtc_h=2 Then the user moves the sprite one pixel to the left resulting on some clipping (the X pixels). Note that the unclipped source coordinates do not change here at all, in fact crtc_x is the only thing changed by the user: FB: CRTC: 0,0 ___ 0.0 __ | abcX | | | | efgX | | | |_| Xgfe | Xcba__| unclipped coordinates specified by user: src_x=2,src_y=0 crtc_x=-1,crtc_y=2 src_w=4.src_h=2 crtc_w= 4,crtc_h=2 clipped coordinates: src_x=2,src_y=0 crtc_x=0,crtc_y=2 src_w=3.src_h=2 crtc_w=3,crtc_h=2 Understood this now. Thank you Ville for providing this elaborate graphical view of the rotation cases. -Sagar -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/