On Fri, 02 Oct 2009 00:07:07 +0100
Stuart Bennett <stuart at freedesktop.org> wrote:
> Pekka Paalanen wrote:
> > Hi Stuart,
> >
> > I'm not sure you know, but annarchy just lost all user homes.
> > Could you push vbtracetool and whatever personal git repos you
> > had, so we can clone them?
>
> Hey Pekka, I've re-upped vbtracetool and radeontool (they haven't
> shown up in cgit just yet, but I imagine they will soon). Can't
> remember if there was anything else particularly useful to other
> folk there, so if I've missed something someone will have to tell
> me.
Thanks for the replies!
I'm in a bit of a hurry right now, so I will get back to this
next week.
> As a bonus (although it's entirely possible this has long been
> dealt with, I've not been following development recently), here's
> the answer to an email of yours from a while ago which I've kept
> forgetting to answer:
>
> Pekka Paalanen wrote:
> > On Thu, 20 Aug 2009 14:40:24 +0300
> > Pekka Paalanen <pq at iki.fi> wrote:
> >
> >> > Hi,
> >> >
> >> > questions will follow.
> >
> > This patch builds, but I have not tried to run it.
> > I'm hoping Stuart or someone could comment on it.
> >
> >> > ---
> >> >
> >> > diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c
> >> > b/drivers/gpu/drm/nouveau/nouveau_bios.c index
> >> > 99f7bd4..13b3fb1 100644 ---
> >> > a/drivers/gpu/drm/nouveau/nouveau_bios.c +++
> >> > b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -40,8 +40,6 @@
> >> > #define BIOSLOG(sip, fmt, arg...) NV_DEBUG(sip->dev, fmt,
> >> > ##arg) #define LOG_OLD_VALUE(x) //x
> >> >
> >> > -#define BIOS_USLEEP(n) mdelay((n)/1000)
> >> > -
> >> > #define ROM16(x) le16_to_cpu(*(uint16_t *)&(x))
> >> > #define ROM32(x) le32_to_cpu(*(uint32_t *)&(x))
> >> >
> >> > @@ -50,6 +48,15 @@ struct init_exec {
> >> > bool repeat;
> >> > };
> >> >
> >> > +static inline void bios_usleep(unsigned usecs)
> >> > +{
> >> > + might_sleep();
> >> > + if (usecs < 1000 * MAX_UDELAY_MS)
> >> > + udelay(usecs);
> >> > + else
> >> > + msleep(usecs / 1000 + 1);
> >> > +}
> >
> > This function is to replace the BIOS_USLEEP() macro with
> > something, that works both for short and long delays.
> > BIOS_USLEEP would truncate all sleeps to milliseconds, meaning
> > delays less than 1000 us would be zero. Also, mdelay() is a
> > busyloop delay burning CPU cycles for nothing. msleep() is not,
> > it will reschedule until the delay has passed. The change
> > raises two questions:
> >
> > - Is the bios code ever called in a situation, where scheduling
> > is not allowed (interrupt context, pre-emption disabled, inside
> > spinlocks, etc.)?
>
> not as far as I know, though I'm uncertain of what the conditions
> are when resuming from suspend
>
> > - Is the delay accuracy on the msleep path critical?
>
> no (but on udelay it possibly is)
>
> btw, does might_sleep() imply a possibility of getting
> rescheduled? If so, you probably only want might_sleep in the
> msleep() (not udelay()) path?
>
> >> > static bool nv_cksum(const uint8_t *data, unsigned int
> >> > length) {
> >> > /* there's a few checksums in the BIOS, so here's a
> >> > generic checking function */ @@ -262,7 +269,7 @@ static int
> >> > parse_init_table(struct nvbios *, unsigned int, struct
> >> > init_exec *); static void still_alive(void) {
> >> > // sync();
> >> > -// BIOS_USLEEP(2000);
> >> > +// bios_usleep(2000);
> >> > }
> >> >
> >> > static uint32_t
> >> > @@ -1608,17 +1615,18 @@ init_condition_time(struct nvbios
> >> > *bios, uint16_t offset,
> >> > for (; retries > 0; retries--)
> >> > if (bios_condition_met(bios, offset, cond))
> >> > {
> >> > - BIOSLOG(bios, "0x%04X: Condition
> >> > met, continuing\n", offset);
> >> > + BIOSLOG(bios, "0x%04X: Condition
> >> > met, continuing\n",
> >> > +
> >> > offset); break;
> >> > } else {
> >> > BIOSLOG(bios, "0x%04X: Condition
> >> > not met, sleeping for 20ms\n", offset);
> >> > - BIOS_USLEEP(20000);
> >> > + bios_usleep(20000);
> >
> > It so happens, that 20000 was the maximum allowed udelay()
> > constant time for x86. Did the number come from that?
>
> no, sheer coincidence
>
> >> > }
> >> >
> >> > if (!bios_condition_met(bios, offset, cond)) {
> >> > NV_WARN(bios->dev,
> >> > "0x%04X: Condition still not met
> >> > after %dms, "
> >> > - "skiping following opcodes\n",
> >> > offset, 20 * retries);
> >> > + "skipping following opcodes\n",
> >> > offset, 20 * retries); iexec->execute = false;
> >> > }
> >> >
> >> > @@ -1851,7 +1859,7 @@ init_reset(struct nvbios *bios,
> >> > uint16_t offset, struct init_exec *iexec) bios_wr32(bios,
> >> > NV_PBUS_PCI_NV_19, 0); bios_wr32(bios, reg, value1);
> >> >
> >> > - BIOS_USLEEP(10);
> >> > + bios_usleep(10);
> >
> > With the old BIOS_USLEEP, this delay would vanish.
>
> an error in the ddx -> drm conversion I think
>
> >> >
> >> > bios_wr32(bios, reg, value2);
> >> > bios_wr32(bios, NV_PBUS_PCI_NV_19, pci_nv_19);
> >> > @@ -2233,8 +2241,7 @@ init_time(struct nvbios *bios,
> >> > uint16_t offset, struct init_exec *iexec) BIOSLOG(bios,
> >> > "0x%04X: Sleeping for 0x%04X microseconds\n",
offset, time);
> >> >
> >> > - BIOS_USLEEP(time);
> >> > -
> >> > + bios_usleep(time);
> >
> > Can here be delay accuracy issues? How much are we allowed to
> > exceed the specified delay?
>
> Shouldn't worry about it. So long as delays are accurate for <
> 1ms, I think slop on greater values is acceptable
>
> >> > return true;
> >> > }
> >> >
> >> > @@ -2872,9 +2879,11 @@ static int
> >> > call_lvds_manufacturer_script(struct drm_device *dev, struct
> >> > dcb_entr run_digital_op_script(dev, scriptofs, dcbent, head,
> >> > bios->fp.dual_link);
> >> > - if (script == LVDS_PANEL_OFF)
> >> > + if (script == LVDS_PANEL_OFF) {
> >> > /* off-on delay in ms */
> >> > -
> >> > BIOS_USLEEP(ROM16(bios->data[bios->fp.xlated_entry +
7]));
> >> > +
> >> > bios_usleep(ROM16(bios->data[bios->fp.xlated_entry +
7]));
> >> > + }
> >
> > The comment and code disagree here. Is it microseconds or
> > milliseconds?
>
> Should be milliseconds, code bug.
>
> Regards
> Stuart
>
--
Pekka Paalanen
http://www.iki.fi/pq/