Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S938549AbcKXJon convert rfc822-to-8bit (ORCPT ); Thu, 24 Nov 2016 04:44:43 -0500 Received: from exsmtp02.microchip.com ([198.175.253.38]:36516 "EHLO email.microchip.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S936303AbcKXJol (ORCPT ); Thu, 24 Nov 2016 04:44:41 -0500 X-Greylist: delayed 385 seconds by postgrey-1.27 at vger.kernel.org; Thu, 24 Nov 2016 04:44:41 EST From: To: CC: , , , , , , , , , , , , Subject: RE: [RFC PATCH v2 1/2] macb: Add 1588 support in Cadence GEM. Thread-Topic: [RFC PATCH v2 1/2] macb: Add 1588 support in Cadence GEM. Thread-Index: AQHSQaeiPm41YNVoFUi9+xh5v0/aZKDit8MAgAR4UICAAFv9AIAAXLeg Date: Thu, 24 Nov 2016 09:36:10 +0000 Message-ID: <07C910AB6AC6C345A093D5A08F5AF568CB7324AA@CHN-SV-EXMX03.mchp-main.com> References: <1479478912-14067-1-git-send-email-andrei.pistirica@microchip.com> <20161120191823.GA6950@localhost.localdomain> <20161123210318.GB2845@localhost.localdomain> In-Reply-To: <20161123210318.GB2845@localhost.localdomain> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.10.76.4] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 8BIT MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3006 Lines: 107 > -----Original Message----- > From: Richard Cochran [mailto:richardcochran@gmail.com] > Sent: Wednesday, November 23, 2016 11:03 PM > To: Andrei Pistirica - M16132 > Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; linux-arm- > kernel@lists.infradead.org; davem@davemloft.net; > nicolas.ferre@atmel.com; harinikatakamlinux@gmail.com; > harini.katakam@xilinx.com; punnaia@xilinx.com; michals@xilinx.com; > anirudh@xilinx.com; boris.brezillon@free-electrons.com; > alexandre.belloni@free-electrons.com; tbultel@pixelsurmer.com > Subject: Re: [RFC PATCH v2 1/2] macb: Add 1588 support in Cadence GEM. > > On Wed, Nov 23, 2016 at 02:34:03PM +0100, Andrei Pistirica wrote: > > From what I understand, your suggestion is: > > (ns | frac) * ppb = (total_ns | total_frac) (total_ns | total_frac) / > > 10^9 = (adj_ns | adj_frac) This is correct iff total_ns/10^9 >= 1, but > > the problem is that there are missed fractions due to the following > > approximation: > > frac*ppb =~ > > (ns*ppb+frac*ppb*2^16)*2^16-10^9*2^16*flor(ns*ppb+frac*ppb*2^16, > > 10^9). > > -ENOPARSE; > > > An example which uses values from a real test: > > let ppb=4891, ns=12 and frac=3158 > > That is a very strange example for nominal frequency. The clock period is > 12.048187255859375 nanoseconds, and so the frequency is > 83000037.99 Hz. > > But hey, let's go with it... > > > - using suggested algorithm, yields: adj_ns = 0 and adj_frac = 0 > > - using in-place algorithm, yields: adj_ns = 0, adj_frac = 4 You can > > check the calculus. > > The test program, below, shows you what I meant. (Of course, you should > adjust this to fit the adjfine() method.) > > Unfortunately, this device has a very coarse frequency resolution. > Using a nominal period of ns=12 as an example, the resolution is > 2^-16 / 12 or 1.27 ppm. The 24 bit device is much better in this repect. > > The output using your example numbers is: > > $ ./a.out 12 3158 4891 > ns=12 frac=3158 > ns=12 frac=3162 > > $ ./a.out 12 3158 -4891 > ns=12 frac=3158 > ns=12 frac=3154 > > See how you get a result of +/- 4 with just one division? > > Thanks, > Richard > > --- > #include > #include > #include > > static void adjfreq(uint32_t ns, uint32_t frac, int32_t ppb) { > uint64_t adj; > uint32_t diff, word; > int neg_adj = 0; > > printf("ns=%u frac=%u\n", ns, frac); > > if (ppb < 0) { > neg_adj = 1; > ppb = -ppb; > } > word = (ns << 16) + frac; > adj = word; > adj *= ppb; > adj += 500000000UL; > diff = adj / 1000000000UL; > > word = neg_adj ? word - diff : word + diff; > printf("ns=%u frac=%u\n", word >> 16, word & 0xffff); } > > int main(int argc, char *argv[]) > { > uint32_t ns, frac; > int32_t ppb; > > if (argc != 4) { > puts("need ns, frac, and ppb"); > return -1; > } > ns = atoi(argv[1]); > frac = atoi(argv[2]); > ppb = atoi(argv[3]); > adjfreq(ns, frac, ppb); > return 0; > } Ok, thanks. I will use this one then. Regards, Andrei