Port the IMX6 kernel configuration to use MULTIDELAY. This will help adding
the i.MX series of SoCs to the armv6 GENERIC kernel. This uses updated times from ian@. Reviewed by: ian Sponsored by: ABT Systems Ltd
This commit is contained in:
parent
9215e501b9
commit
4bd9887cd5
@ -32,6 +32,7 @@ options INCLUDE_CONFIG_FILE # Include this file in kernel
|
||||
options PLATFORM
|
||||
options PLATFORM_SMP
|
||||
options SMP # Enable multiple cores
|
||||
options MULTIDELAY
|
||||
|
||||
# NFS root from boopt/dhcp
|
||||
#options BOOTP
|
||||
|
@ -324,7 +324,7 @@ static platform_method_t imx6_methods[] = {
|
||||
PLATFORMMETHOD_END,
|
||||
};
|
||||
|
||||
FDT_PLATFORM_DEF2(imx6, imx6s, "i.MX6 Solo", 0, "fsl,imx6s", 0);
|
||||
FDT_PLATFORM_DEF2(imx6, imx6d, "i.MX6 Dual", 0, "fsl,imx6dl", 0);
|
||||
FDT_PLATFORM_DEF2(imx6, imx6q, "i.MX6 Quad", 0, "fsl,imx6q", 0);
|
||||
FDT_PLATFORM_DEF2(imx6, imx6ul, "i.MX6 UltraLite", 0, "fsl,imx6ul", 0);
|
||||
FDT_PLATFORM_DEF2(imx6, imx6s, "i.MX6 Solo", 0, "fsl,imx6s", 80);
|
||||
FDT_PLATFORM_DEF2(imx6, imx6d, "i.MX6 Dual", 0, "fsl,imx6dl", 80);
|
||||
FDT_PLATFORM_DEF2(imx6, imx6q, "i.MX6 Quad", 0, "fsl,imx6q", 80);
|
||||
FDT_PLATFORM_DEF2(imx6, imx6ul, "i.MX6 UltraLite", 0, "fsl,imx6ul", 67);
|
||||
|
@ -40,6 +40,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/timetc.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/intr.h>
|
||||
#ifdef MULTIDELAY
|
||||
#include <machine/machdep.h> /* For arm_set_delay */
|
||||
#endif
|
||||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
@ -62,6 +65,8 @@ static int imx_gpt_timer_start(struct eventtimer *, sbintime_t,
|
||||
sbintime_t);
|
||||
static int imx_gpt_timer_stop(struct eventtimer *);
|
||||
|
||||
static void imx_gpt_do_delay(int, void *);
|
||||
|
||||
static int imx_gpt_intr(void *);
|
||||
static int imx_gpt_probe(device_t);
|
||||
static int imx_gpt_attach(device_t);
|
||||
@ -87,6 +92,7 @@ struct imx_gpt_softc {
|
||||
struct eventtimer et;
|
||||
};
|
||||
|
||||
#ifndef MULTIDELAY
|
||||
/* Global softc pointer for use in DELAY(). */
|
||||
static struct imx_gpt_softc *imx_gpt_sc;
|
||||
|
||||
@ -98,6 +104,7 @@ static struct imx_gpt_softc *imx_gpt_sc;
|
||||
* we're attached the delay loop switches to using the timer hardware.
|
||||
*/
|
||||
static const int imx_gpt_delay_count = 78;
|
||||
#endif
|
||||
|
||||
/* Try to divide down an available fast clock to this frequency. */
|
||||
#define TARGET_FREQUENCY 1000000000
|
||||
@ -275,8 +282,13 @@ imx_gpt_attach(device_t dev)
|
||||
tc_init(&imx_gpt_timecounter);
|
||||
|
||||
/* If this is the first unit, store the softc for use in DELAY. */
|
||||
if (device_get_unit(dev) == 0)
|
||||
imx_gpt_sc = sc;
|
||||
if (device_get_unit(dev) == 0) {
|
||||
#ifdef MULTIDELAY
|
||||
arm_set_delay(imx_gpt_do_delay, sc);
|
||||
#else
|
||||
imx_gpt_sc = sc;
|
||||
#endif
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -396,19 +408,12 @@ static devclass_t imx_gpt_devclass;
|
||||
EARLY_DRIVER_MODULE(imx_gpt, simplebus, imx_gpt_driver, imx_gpt_devclass, 0,
|
||||
0, BUS_PASS_TIMER);
|
||||
|
||||
void
|
||||
DELAY(int usec)
|
||||
static void
|
||||
imx_gpt_do_delay(int usec, void *arg)
|
||||
{
|
||||
struct imx_gpt_softc *sc = arg;
|
||||
uint64_t curcnt, endcnt, startcnt, ticks;
|
||||
|
||||
/* If the timer hardware is not accessible, just use a loop. */
|
||||
if (imx_gpt_sc == NULL) {
|
||||
while (usec-- > 0)
|
||||
for (ticks = 0; ticks < imx_gpt_delay_count; ++ticks)
|
||||
cpufunc_nullop();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the tick count with 64-bit values so that it works for any
|
||||
* clock frequency. Loop until the hardware count reaches start+ticks.
|
||||
@ -417,12 +422,30 @@ DELAY(int usec)
|
||||
* that doing this on each loop iteration is inefficient -- we're trying
|
||||
* to waste time here.
|
||||
*/
|
||||
ticks = 1 + ((uint64_t)usec * imx_gpt_sc->clkfreq) / 1000000;
|
||||
curcnt = startcnt = READ4(imx_gpt_sc, IMX_GPT_CNT);
|
||||
ticks = 1 + ((uint64_t)usec * sc->clkfreq) / 1000000;
|
||||
curcnt = startcnt = READ4(sc, IMX_GPT_CNT);
|
||||
endcnt = startcnt + ticks;
|
||||
while (curcnt < endcnt) {
|
||||
curcnt = READ4(imx_gpt_sc, IMX_GPT_CNT);
|
||||
curcnt = READ4(sc, IMX_GPT_CNT);
|
||||
if (curcnt < startcnt)
|
||||
curcnt += 1ULL << 32;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef MULTIDELAY
|
||||
void
|
||||
DELAY(int usec)
|
||||
{
|
||||
uint64_t ticks;
|
||||
|
||||
/* If the timer hardware is not accessible, just use a loop. */
|
||||
if (imx_gpt_sc == NULL) {
|
||||
while (usec-- > 0)
|
||||
for (ticks = 0; ticks < imx_gpt_delay_count; ++ticks)
|
||||
cpufunc_nullop();
|
||||
return;
|
||||
} else
|
||||
imx_gpt_do_delay(usec, imx_gpt_sc);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user