Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Aug 2018 17:16:26 +0200
From:      Gary Jennejohn <gljennjohn@gmail.com>
To:        Ian Lepore <ian@freebsd.org>
Cc:        Rajesh Kumar <rajfbsd@gmail.com>, freebsd-hackers@freebsd.org, freebsd-drivers@freebsd.org
Subject:   Re: Need a clarification regarding I2C bus frequency in FreeBSD
Message-ID:  <20180821171626.49951728@ernst.home>
In-Reply-To: <1534861980.27158.145.camel@freebsd.org>
References:  <CAAO%2BANOXwXAzJt%2BBZez6422jqKjrKPboSe_%2BudnOCWxYqE-=sQ@mail.gmail.com> <1534523216.27158.17.camel@freebsd.org> <CAAO%2BANOs_YVov-d21Em1EHzajQw7wHsxkzZCnsZwkfBr2=mEiA@mail.gmail.com> <1534702861.27158.36.camel@freebsd.org> <BF721728-B6F5-4214-9180-B911D32D9FCA@cs.huji.ac.il> <A8202939-328A-4564-9CF5-F5F66F68B7B0@cs.huji.ac.il> <1534771095.27158.46.camel@freebsd.org> <35F2C250-B4CB-4C53-BF8F-43C338022E34@yahoo.com> <20180820181322.71607854@ernst.home> <CAAO%2BANOFkm96HJjSTfq7=qw__L8BDFjh=ZK%2BzhYLFFkcahcE7g@mail.gmail.com> <1534861980.27158.145.camel@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 21 Aug 2018 08:33:00 -0600
Ian Lepore <ian@freebsd.org> wrote:

> On Mon, 2018-08-20 at 23:25 +0530, Rajesh Kumar wrote:
> > Hi,
> > 
> > Re-posting the questions, just in case if its missed in other conversation.
> > 
> > By "i2c clock frequency", I mean the internal base frequency only, which
> > drives the chip.____I thought data will be transferred on bus based on the
> > base frequency. So, thought both bus and base frequency are same. But from
> > what you said, seems both are different. So, based on the setting in
> > *_HCNT/LCNT register, the bus frequency (which is the rate at which data is
> > transferred) will change for a particular base frequency. Is that right?
> > 
> > So, few questions here
> > 
> > 1)____As you said, we need to have a base frequency of 150 Mhz in our case.
> > So, do we need to program that IG4_REG_CLK_PARMS to 150 Mhz (0x8F0D180)?
> > And can this be done at the same time when programming the HCNT/LNCT
> > registers?  
> 
> I don't have this hardware, and I don't have a datasheet that describes
> the__IG4_REG_CLK_PARMS register mentioned in the driver, so I don't
> really have an answer. I suspect the hardware should set that register
> with information that lets the driver know what the base clock speed
> is. Using that information, the driver could calculate the proper
> values for HCNT/LCNT.
> 
> Right now the driver lacks *any* support for changing bus speeds. That
> will be easy to fix, once we figure out:
> 
> __1. What is in the IG4_REG_CLK_PARMS register?
> __2. What do we do about versions of the hardware that don't support
> that register?__
> 
> > 2)____Not sure how that 111Hz value is arrived.____Can you please explain this
> > calculation. So, that I can derive the appropriate values for HCNT/LCNT for
> > different speeds at 150Mhz base clock.  
> 
> It's based on the comment (which I feel certain must be wrong) that the
> base clock is 25,000 Hz. With HCNT,LCNT set to 100,125, one cycle of
> the SCL line will last 225 base clock cycles. 1/25000 = 0.000040, that
> times 225 is 0.009 seconds per SCL cycle. 1/.009 = 111.111 Hz.
> 
> FWIW, an i2c bus will run fine at 111Hz, it'll just take forever to get
> anything done. But I don't think the bus is really running at 111Hz,
> because I don't think the base clock is really 25KHz, I think the
> comment block is just wrong about all of that.
> 
> > 3)____"Default HCNT/LCNT register values would be consistent with an internal
> > base clock speed of 1GHz",____Does it mean with those values, all speeds can
> > be achieved until 1GHz clock?
> >   
> 
> Well, the defaults I mentioned are from the datasheet cited in the
> driver code. Those defaults made me think the base clock was 1GHz on
> that particular hardware. I just realized that I was off by an order of
> magnitude, I think I was mixing numbers from the driver and numbers
> from the datasheet in my head. __The default HCNT,LCNT in that datasheet
> are 612+706=1318 base cycles to give an SCL rate of 100KHz. So
> 1318*100000 is 131.8MHz, a very reasonable number.
> 
> In your world you want the 150MHz base clock to generate the 100Hz SCL,
> so 150000000/100000 = 1500. My inclination would be to split that in
> half and have HCNT,LCNT be 750,750, but for some reason there seems to
> be a bias on this hardware for having HCNT be slightly longer than
> LCNT, so maybe 775,725. Maybe that's an attempt to compensate for the
> fact that high levels on the clock line are accomplished with a pullup
> resistor, and it takes slightly longer for the line to "drift up" to a
> high state via the pullup, compared to being driven low which would
> happen quickly.
> 

Just a remark.

According to Table 10 in Chapter 6 of the I2C standard from NXP,
SCL low must satisfy a minimum of 4.7 uS and SCL high must
satisfy a minimum of 4.0 uS when running SCL at 100KHz.  At
400KHz the values are respectively 1.3uS and 0.6uS.

725 results in 4.83uS, which would be OK for the low phase if it
gets pulled low quite quickly.  775 results in 5.17uS, which is
also acceptable, especially if it takes rather long for it to be
pulled up.

750 results in 5.0uS for each, of course.  This may theoreticalluy
be a safer value, but it doesn't reflect any odd behavior which the
real hardware may exhibit.

> I would expect the default values of the HCNT/LCNT registers would be
> right for any given hardware... whoever configures the IP block in a
> SoC would configure the base clock value and the default HCNT/LCNT
> values to match each other. Putting it that way makes me think that
> maybe the right thing to do in the driver is just stop setting
> HCNT/LCNT at all, and rely on the hardware to be configured correctly
> by default. It's worth a try.
> 
> It would also be interesting to just print out those values. In the
> driver on lines 571-575 the code reads all those registers and does
> nothing with them. If you look in the dragonflybsd version of the
> driver it printed out all those values after reading them; whoever
> imported the driver to freebsd just deleted all the kprintf() lines and
> left the register reads.
> 


-- 
Gary Jennejohn



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20180821171626.49951728>