Am 26.04.2013 um 17:09 schrieb Raphael Graf <[email protected]>:
> On Thu, April 25, 2013 7:30 pm, Alexey E. Suslikov wrote:
>> Raphael Graf <r <at> undefined.ch> writes:
>>
>>> I have a beaglebone (AM3359) running OpenBSD, see below.
>>> Is there any interest in such code?
>>
>> Diffs are interesting. Teasers are not.
>>
>
> So here's what I have at the moment.
> Some parts are just horrible hacks (notably the prcm stuff), beware.
> I'll start sending (smaller) diffs when ready.
Sounds good!
I'm currently sorting out diffs to improve ARMv7 and Beagle-/PandaBoard
support and am committing them into the tree, so there will be some changes.
Without looking at the pmap.c change:
There's an ARMv7 version of pmap.c (called pmap7.c), which will
be used for ARMv7 boards, that means also the BeagleBone.
It's not ready yet (in the tree) but we're working on it.
I don't have much time today, so I couldn't really look at the diff,
but I'll send you another mail later.
\Patrick
>
> Index: beagle/beagle_machdep.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/beagle/beagle/beagle_machdep.c,v
> retrieving revision 1.15
> diff -u -p -u -p -r1.15 beagle_machdep.c
> --- beagle/beagle_machdep.c 30 Aug 2012 15:51:13 -0000 1.15
> +++ beagle/beagle_machdep.c 26 Apr 2013 14:43:24 -0000
> @@ -882,6 +882,9 @@ initarm(void *arg0, void *arg1, void *ar
> case BOARD_ID_OMAP3_BEAGLE:
> printf("board type: beagle\n");
> break;
> + case BOARD_ID_AM335X_BEAGLEBONE:
> + printf("board type: beaglebone\n");
> + break;
> case BOARD_ID_OMAP3_OVERO:
> printf("board type: overo\n");
> break;
> @@ -979,6 +982,9 @@ consinit(void)
> case BOARD_ID_OMAP3_BEAGLE:
> case BOARD_ID_OMAP3_OVERO:
> paddr = 0x49020000;
> + break;
> + case BOARD_ID_AM335X_BEAGLEBONE:
> + paddr = 0x44E09000; /* UART0 */
> break;
> case BOARD_ID_OMAP4_PANDA:
> paddr = 0x48020000;
> Index: conf/GENERIC
> ===================================================================
> RCS file: /cvs/src/sys/arch/beagle/conf/GENERIC,v
> retrieving revision 1.14
> diff -u -p -u -p -r1.14 GENERIC
> --- conf/GENERIC 27 Sep 2012 14:01:35 -0000 1.14
> +++ conf/GENERIC 26 Apr 2013 14:43:24 -0000
> @@ -68,6 +68,7 @@ prcm* at soc? # power/clock
> controlle
> omdog* at soc? # watchdog timer
> omgpio* at soc? # user-visible GPIO pins?
> gptimer* at soc? # general purpose timers
> +dmtimer* at soc? # general purpose timers
> ommmc* at soc? # SD/MMC card controller
> omusbtll* at soc?
>
> Index: conf/RAMDISK
> ===================================================================
> RCS file: /cvs/src/sys/arch/beagle/conf/RAMDISK,v
> retrieving revision 1.16
> diff -u -p -u -p -r1.16 RAMDISK
> --- conf/RAMDISK 27 Sep 2012 14:01:35 -0000 1.16
> +++ conf/RAMDISK 26 Apr 2013 14:43:24 -0000
> @@ -73,6 +73,7 @@ prcm* at soc? # power/clock
> controlle
> omdog* at soc? # watchdog timer
> omgpio* at soc? # user-visible GPIO pins?
> gptimer* at soc? # general purpose timers
> +dmtimer* at soc? # general purpose timers
> ommmc* at soc? # SD/MMC card controller
> omusbtll* at soc?
>
> Index: conf/files.beagle
> ===================================================================
> RCS file: /cvs/src/sys/arch/beagle/conf/files.beagle,v
> retrieving revision 1.12
> diff -u -p -u -p -r1.12 files.beagle
> --- conf/files.beagle 27 Mar 2013 17:33:13 -0000 1.12
> +++ conf/files.beagle 26 Apr 2013 14:43:24 -0000
> @@ -31,6 +31,7 @@ attach omap at mainbus
> file arch/beagle/dev/omap.c omap
> file arch/beagle/dev/omap3.c omap
> file arch/beagle/dev/omap4.c omap
> +file arch/beagle/dev/am335x.c omap
>
> # cortex based peripherals
> device ampintc
> @@ -62,6 +63,10 @@ file arch/beagle/dev/intc.c intc
> device gptimer
> attach gptimer at soc
> file arch/beagle/dev/gptimer.c gptimer
> +
> +device dmtimer
> +attach dmtimer at soc
> +file arch/beagle/dev/dmtimer.c dmtimer
>
> device omdog
> attach omdog at soc
> Index: dev/am335x.c
> ===================================================================
> RCS file: dev/am335x.c
> diff -N dev/am335x.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ dev/am335x.c 26 Apr 2013 14:43:24 -0000
> @@ -0,0 +1,161 @@
> +/* $OpenBSD: omap3.c,v 1.4 2011/11/10 23:43:01 uwe Exp $ */
> +
> +/*
> + * Copyright (c) 2011 Uwe Stuehler <[email protected]>
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#include <sys/types.h>
> +#include <sys/param.h>
> +#include <machine/bus.h>
> +
> +#include <beagle/dev/omapvar.h>
> +
> +#define PRCM_ADDR 0x44E00000
> +#define PRCM_SIZE 0x2000
> +
> +#define INTC_ADDR 0x48200000
> +#define INTC_SIZE 0x1000
> +#define INTC_NUM_IRQ 128
> +
> +#define DMTIMERx_SIZE 0x1000
> +#define DMTIMER0_ADDR 0x44E05000
> +#define DMTIMER1_ADDR 0x44E31000 /* 1MS */
> +#define DMTIMER2_ADDR 0x48040000
> +#define DMTIMER3_ADDR 0x48042000
> +#define DMTIMER4_ADDR 0x48044000
> +#define DMTIMER5_ADDR 0x48046000
> +#define DMTIMER6_ADDR 0x48048000
> +#define DMTIMER7_ADDR 0x4804A000
> +
> +#define DMTIMER0_IRQ 66
> +#define DMTIMER1_IRQ 67
> +#define DMTIMER2_IRQ 68
> +#define DMTIMER3_IRQ 69
> +#define DMTIMER4_IRQ 92
> +#define DMTIMER5_IRQ 93
> +#define DMTIMER6_IRQ 94
> +#define DMTIMER7_IRQ 95
> +
> +#define WD_ADDR 0x44E35000
> +#define WD_SIZE 0x80
> +
> +#define GPIOx_SIZE 0x1000
> +#define GPIO0_ADDR 0x44E07000
> +#define GPIO1_ADDR 0x4804C000
> +#define GPIO2_ADDR 0x481AC000
> +#define GPIO3_ADDR 0x481AE000
> +
> +#define GPIO0_IRQ 96
> +#define GPIO1_IRQ 98
> +#define GPIO2_IRQ 32
> +#define GPIO3_IRQ 62
> +
> +#define UARTx_SIZE 0x400
> +#define UART0_ADDR 0x44E09000
> +#define UART1_ADDR 0x48022000
> +#define UART2_ADDR 0x48024000
> +#define UART3_ADDR 0x481A6000
> +#define UART4_ADDR 0x481A8000
> +#define UART5_ADDR 0x481AA000
> +
> +#define UART0_IRQ 72
> +#define UART1_IRQ 73
> +#define UART2_IRQ 74
> +#define UART3_IRQ 44
> +#define UART4_IRQ 45
> +#define UART5_IRQ 46
> +
> +#define HSMMCx_SIZE 0x200
> +#define HSMMC0_ADDR 0x48060000
> +#define HSMMC0_IRQ 64
> +
> +#define USBTLL_ADDR 0x48062000
> +#define USBTLL_SIZE 0x1000
> +
> +struct omap_dev am335x_devs[] = {
> +
> + /*
> + * Power, Reset and Clock Manager
> + */
> +
> + { .name = "prcm",
> + .unit = 0,
> + .mem = { { PRCM_ADDR, PRCM_SIZE } },
> + },
> +
> + /*
> + * Interrupt Controller
> + */
> +
> + { .name = "intc",
> + .unit = 0,
> + .mem = { { INTC_ADDR, INTC_SIZE } },
> + },
> +
> + /*
> + * General Purpose Timers
> + */
> +
> + { .name = "dmtimer",
> + .unit = 1, /* XXX see gptimer.c */
> + .mem = { { DMTIMER2_ADDR, DMTIMERx_SIZE } },
> + .irq = { DMTIMER2_IRQ }
> + },
> +
> + { .name = "dmtimer",
> + .unit = 0, /* XXX see gptimer.c */
> + .mem = { { DMTIMER3_ADDR, DMTIMERx_SIZE } },
> + .irq = { DMTIMER3_IRQ }
> + },
> +
> + /*
> + * Watchdog Timer
> + */
> +
> + { .name = "omdog",
> + .unit = 0,
> + .mem = { { WD_ADDR, WD_SIZE } }
> + },
> +
> + /*
> + * UART
> + */
> +
> + { .name = "com",
> + .unit = 0,
> + .mem = { { UART0_ADDR, UARTx_SIZE } },
> + .irq = { UART0_IRQ }
> + },
> +
> + /*
> + * MMC
> + */
> +
> + { .name = "ommmc",
> + .unit = 0,
> + .mem = { { HSMMC0_ADDR, HSMMCx_SIZE } },
> + .irq = { HSMMC0_IRQ }
> + },
> +
> + { .name = NULL,
> + .unit = 0
> + }
> +};
> +
> +void
> +am335x_init(void)
> +{
> + omap_set_devs(am335x_devs);
> +}
> Index: dev/dmtimer.c
> ===================================================================
> RCS file: dev/dmtimer.c
> diff -N dev/dmtimer.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ dev/dmtimer.c 26 Apr 2013 14:43:24 -0000
> @@ -0,0 +1,440 @@
> +/*
> + * Copyright (c) 2007,2009 Dale Rahn <[email protected]>
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +/*
> + * WARNING - this timer initializion has not been checked
> + * to see if it will do _ANYTHING_ sane if the omap enters
> + * low power mode.
> + */
> +
> +#include <sys/types.h>
> +#include <sys/param.h>
> +#include <sys/systm.h>
> +#include <sys/kernel.h>
> +#include <sys/time.h>
> +#include <sys/evcount.h>
> +#include <sys/device.h>
> +#include <sys/timetc.h>
> +#include <dev/clock_subr.h>
> +#include <machine/bus.h>
> +#include <beagle/dev/omapvar.h>
> +#include <beagle/dev/prcmvar.h>
> +
> +#include <machine/intr.h>
> +#include <arm/cpufunc.h>
> +
> +/* registers */
> +#define DM_TIDR 0x000 /* revision */
> +#define DM_TIOCP_CFG 0x010
> +#define DM_TIOCP_CFG_IDLEMODE 0x0000000c
> +#define DM_TIOCP_CFG_EMUFREE 0x00000002
> +#define DM_TIOCP_CFG_SOFTRESET 0x00000001
> +#define DM_TISR 0x028 /* timer irq
> status register*/
> +#define GP_TISTAT_TCAR 0x00000004
> +#define GP_TISTAT_OVF 0x00000002
> +#define GP_TISTAT_MATCH 0x00000001
> +#define DM_TIER 0x2c /* timer irq
> enable set register (set only!!!) */
> +#define DM_TIER_TCAR_EN 0x4
> +#define DM_TIER_OVF_EN 0x2
> +#define DM_TIER_MAT_EN 0x1
> +#define DM_TWER 0x034 /* timer wakeup
> enable register */
> +#define DM_TWER_TCAR_EN 0x00000004
> +#define DM_TWER_OVF_EN 0x00000002
> +#define DM_TWER_MAT_EN 0x00000001
> +#define DM_TCLR 0x038 /* timer
> control register*/
> +#define DM_TCLR_GPO (1<<14)
> +#define DM_TCLR_CAPT (1<<13)
> +#define DM_TCLR_PT (1<<12)
> +#define DM_TCLR_TRG (3<<10)
> +#define DM_TCLR_TRG_O (1<<10)
> +#define DM_TCLR_TRG_OM (2<<10)
> +#define DM_TCLR_TCM (3<<8)
> +#define DM_TCLR_TCM_RISE (1<<8)
> +#define DM_TCLR_TCM_FALL (2<<8)
> +#define DM_TCLR_TCM_BOTH (3<<8)
> +#define DM_TCLR_SCPWM (1<<7)
> +#define DM_TCLR_CE (1<<6)
> +#define DM_TCLR_PRE (1<<5)
> +#define DM_TCLR_PTV (7<<2)
> +#define DM_TCLR_AR (1<<1)
> +#define DM_TCLR_ST (1<<0)
> +#define DM_TCRR 0x03c /* counter */
> +#define DM_TLDR 0x040 /* reload */
> +#define DM_TTGR 0x044
> +#define DM_TWPS 0x048 /* write posted
> status register*/
> +#define DM_TWPS_TCLR 0x01
> +#define DM_TWPS_TCRR 0x02
> +#define DM_TWPS_TLDR 0x04
> +#define DM_TWPS_TTGR 0x08
> +#define DM_TWPS_TMAR 0x10
> +#define DM_TWPS_ALL 0x1f
> +#define DM_TMAR 0x04c
> +#define DM_TCAR 0x050
> +#define GP_TSICR 0x054
> +#define GP_TSICR_POSTED 0x00000002
> +#define GP_TSICR_SFT 0x00000001
> +#define DM_TCAR2 0x058
> +
> +#define TIMER_FREQUENCY 32768 /* 32kHz is used,
> selectable */
> +
> +static struct evcount clk_count;
> +static struct evcount stat_count;
> +
> +void dmtimer_attach(struct device *parent, struct device *self, void *args);
> +int dmtimer_intr(void *frame);
> +void dmtimer_wait(int reg);
> +void dmtimer_cpu_initclocks(void);
> +void dmtimer_delay(u_int);
> +void dmtimer_setstatclockrate(int newhz);
> +
> +bus_space_tag_t dmtimer_iot;
> +bus_space_handle_t dmtimer_ioh0, dmtimer_ioh1 = 0;
> +int dmtimer_irq = 0;
> +
> +u_int dmtimer_get_timecount(struct timecounter *);
> +
> +static struct timecounter dmtimer_timecounter = {
> + dmtimer_get_timecount, NULL, 0x7fffffff, 0, "dmtimer", 0, NULL
> +};
> +
> +volatile u_int32_t nexttickevent;
> +volatile u_int32_t nextstatevent;
> +u_int32_t ticks_per_second;
> +u_int32_t ticks_per_intr;
> +u_int32_t ticks_err_cnt;
> +u_int32_t ticks_err_sum;
> +u_int32_t statvar, statmin;
> +
> +struct cfattach dmtimer_ca = {
> + sizeof (struct device), NULL, dmtimer_attach
> +};
> +
> +struct cfdriver dmtimer_cd = {
> + NULL, "dmtimer", DV_DULL
> +};
> +
> +void
> +dmtimer_attach(struct device *parent, struct device *self, void *args)
> +{
> + struct omap_attach_args *oa = args;
> + bus_space_handle_t ioh;
> + u_int32_t rev;
> +
> + dmtimer_iot = oa->oa_iot;
> +
> + if (bus_space_map(dmtimer_iot, oa->oa_dev->mem[0].addr,
> + oa->oa_dev->mem[0].size, 0, &ioh))
> + panic("dmtimer_attach: bus_space_map failed!\n");
> +
> + prcm_setclock(1, PRCM_CLK_SPEED_32);
> + prcm_setclock(2, PRCM_CLK_SPEED_32);
> +
> + prcm_enablemodule(AM335X_PRCM_CM_PER_TIMER2_CLKCTRL);
> + prcm_enablemodule(AM335X_PRCM_CM_PER_TIMER3_CLKCTRL);
> +
> + rev = bus_space_read_4(dmtimer_iot, ioh, DM_TIDR);
> +
> + printf(" rev %d.%d\n", rev >> 4 & 0xf, rev & 0xf);
> +
> + if (self->dv_unit == 0) { /* timer 2*/
> + dmtimer_ioh0 = ioh;
> + dmtimer_irq = oa->oa_dev->irq[0];
> + bus_space_write_4(dmtimer_iot, dmtimer_ioh0, DM_TCLR, 0); /*
> timer control register, stop timer */
> + } else if (self->dv_unit == 1) { /* timer 3*/
> + /* start timer because it is used in delay */
> + /* interrupts are disabled */
> + dmtimer_ioh1 = ioh;
> + bus_space_write_4(dmtimer_iot, dmtimer_ioh1, DM_TCRR, 0); /*
> timer counter register */
> + dmtimer_wait(DM_TWPS_ALL);
> + bus_space_write_4(dmtimer_iot, dmtimer_ioh1, DM_TLDR, 0); /*
> timer load register */
> + dmtimer_wait(DM_TWPS_ALL);
> + bus_space_write_4(dmtimer_iot, dmtimer_ioh1, DM_TCLR,
> + DM_TCLR_AR | DM_TCLR_ST);
> + dmtimer_wait(DM_TWPS_ALL);
> +
> + dmtimer_timecounter.tc_frequency = TIMER_FREQUENCY;
> + tc_init(&dmtimer_timecounter);
> + }
> + else
> + panic("attaching too many dmtimers at 0x%x",
> + oa->oa_dev->mem[0].addr);
> +
> + arm_clock_register(dmtimer_cpu_initclocks, dmtimer_delay,
> + dmtimer_setstatclockrate);
> +}
> +
> +/*
> + * See comment in arm/xscale/i80321_clock.c
> + *
> + * counter is count up, but with autoreload timers it is not possible
> + * to detect how many interrupts passed while interrupts were blocked.
> + * also it is not possible to atomically add to the register
> + * get get it to precisely fire at a non-fixed interval.
> + *
> + * To work around this two timers are used, GPT1 is used as a reference
> + * clock without reload , however we just ignore the interrupt it
> + * would (may?) generate.
> + *
> + * Internally this keeps track of when the next timer should fire
> + * and based on that time and the current value of the reference
> + * clock a number is written into the timer count register to schedule
> + * the next event.
> + */
> +
> +int
> +dmtimer_intr(void *frame)
> +{
> + u_int32_t now, r;
> + u_int32_t nextevent, duration;
> +
> + /* read the free running counter */
> + now = bus_space_read_4(dmtimer_iot, dmtimer_ioh1, DM_TCRR);
> +
> + while ((int32_t) (nexttickevent - now) < 0) {
> + nexttickevent += ticks_per_intr;
> + ticks_err_sum += ticks_err_cnt;
> +#if 0
> + if (ticks_err_sum > hz) {
> + u_int32_t match_error;
> + match_error = ticks_err_sum / hz
> + ticks_err_sum -= (match_error * hz);
> + }
> +#else
> + /* looping a few times is faster than divide */
> + while (ticks_err_sum > hz) {
> + nexttickevent += 1;
> + ticks_err_sum -= hz;
> + }
> +#endif
> + clk_count.ec_count++;
> + hardclock(frame);
> + }
> +
> + while ((int32_t) (nextstatevent - now) < 0) {
> + do {
> + r = random() & (statvar -1);
> + } while (r == 0); /* random == 0 not allowed */
> + nextstatevent += statmin + r;
> + /* XXX - correct nextstatevent? */
> + stat_count.ec_count++;
> + statclock(frame);
> + }
> + if ((now - nexttickevent) < (now - nextstatevent))
> + nextevent = nexttickevent;
> + else
> + nextevent = nextstatevent;
> +
> +/* XXX */
> + duration = nextevent -
> + bus_space_read_4(dmtimer_iot, dmtimer_ioh1, DM_TCRR);
> +#if 0
> + printf("duration 0x%x %x %x\n", nextevent -
> + bus_space_read_4(dmtimer_iot, dmtimer_ioh1, DM_TCRR),
> + bus_space_read_4(dmtimer_iot, dmtimer_ioh0, DM_TCRR),
> + bus_space_read_4(dmtimer_iot, dmtimer_ioh1, DM_TCRR));
> +#endif
> +
> +
> + if (duration <= 0)
> + duration = 1; /* trigger immediately. */
> +
> + if (duration > ticks_per_intr) {
> + /*
> + * If interrupts are blocked too long, like during
> + * the root prompt or ddb, the timer can roll over,
> + * this will allow the system to continue to run
> + * even if time is lost.
> + */
> + duration = ticks_per_intr;
> + nexttickevent = now;
> + nextstatevent = now;
> + }
> +
> + dmtimer_wait(DM_TWPS_ALL);
> + bus_space_write_4(dmtimer_iot, dmtimer_ioh0, DM_TISR,
> + bus_space_read_4(dmtimer_iot, dmtimer_ioh0, DM_TISR));
> + bus_space_write_4(dmtimer_iot, dmtimer_ioh0, DM_TISR, 7);
> + dmtimer_wait(DM_TWPS_ALL);
> + bus_space_write_4(dmtimer_iot, dmtimer_ioh0, DM_TCRR, -duration); /*
> set counter of timer 2 */
> +
> + return 1;
> +}
> +
> +/*
> + * would be interesting to play with trigger mode while having one timer
> + * in 32KHz mode, and the other timer running in sysclk mode and use
> + * the high resolution speeds (matters more for delay than tick timer
> + */
> +
> +void
> +dmtimer_cpu_initclocks()
> +{
> + stathz = 128;
> + profhz = 1024;
> +
> + ticks_per_second = TIMER_FREQUENCY; /* 32768 */
> +
> + setstatclockrate(stathz);
> +
> + ticks_per_intr = ticks_per_second / hz;
> + ticks_err_cnt = ticks_per_second % hz;
> + ticks_err_sum = 0;
> +
> + prcm_setclock(1, PRCM_CLK_SPEED_32);
> + prcm_setclock(2, PRCM_CLK_SPEED_32);
> + /* establish interrupts */
> + arm_intr_establish(dmtimer_irq, IPL_CLOCK, dmtimer_intr, /*
> timer 2 irq */
> + NULL, "tick");
> +
> + /* setup timer 0 (hardware timer 3) */
> + /* reset? - XXX */
> +
> + bus_space_write_4(dmtimer_iot, dmtimer_ioh0, DM_TLDR, 0); /*
> value loaded on overflow */
> +
> + nexttickevent = nextstatevent = bus_space_read_4(dmtimer_iot,
> + dmtimer_ioh1, DM_TCRR) + ticks_per_intr;
> +
> + dmtimer_wait(DM_TWPS_ALL);
> + bus_space_write_4(dmtimer_iot, dmtimer_ioh0, DM_TIER, DM_TIER_OVF_EN);
> /* timer interrupt on overflow enable (timer 2)*/
> + dmtimer_wait(DM_TWPS_ALL);
> + bus_space_write_4(dmtimer_iot, dmtimer_ioh0, DM_TWER, DM_TWER_OVF_EN);
> + dmtimer_wait(DM_TWPS_ALL);
> + bus_space_write_4(dmtimer_iot, dmtimer_ioh0, DM_TCLR, /* timter control
> reg. autoreload and start */
> + DM_TCLR_AR | DM_TCLR_ST);
> + dmtimer_wait(DM_TWPS_ALL);
> + bus_space_write_4(dmtimer_iot, dmtimer_ioh0, DM_TISR, /*clear
> interrupt flags */
> + bus_space_read_4(dmtimer_iot, dmtimer_ioh0, DM_TISR));
> + dmtimer_wait(DM_TWPS_ALL);
> + bus_space_write_4(dmtimer_iot, dmtimer_ioh0, DM_TCRR, -ticks_per_intr);
> /* set counter value to -ticks_per_intr */
> + dmtimer_wait(DM_TWPS_ALL);
> +}
> +
> +void
> +dmtimer_wait(int reg)
> +{
> + while (bus_space_read_4(dmtimer_iot, dmtimer_ioh0, DM_TWPS) & reg)
> + ;
> +}
> +
> +#if 0
> +void
> +microtime(struct timeval *tvp)
> +{
> + int s;
> + int deltacnt;
> + u_int32_t counter, expected;
> + s = splhigh();
> +
> + if (1) { /* not inited */
> + tvp->tv_sec = 0;
> + tvp->tv_usec = 0;
> + return;
> + }
> + s = splhigh();
> + counter = bus_space_read_4(dmtimer_iot, dmtimer_ioh1, DM_TCRR);
> + expected = nexttickevent;
> +
> + *tvp = time;
> + splx(s);
> +
> + deltacnt = counter - expected + ticks_per_intr;
> +
> +#if 1
> + /* low frequency timer algorithm */
> + tvp->tv_usec += deltacnt * 1000000ULL / TIMER_FREQUENCY;
> +#else
> + /* high frequency timer algorithm - XXX */
> + tvp->tv_usec += deltacnt / (TIMER_FREQUENCY / 1000000ULL);
> +#endif
> +
> + while (tvp->tv_usec >= 1000000) {
> + tvp->tv_sec++;
> + tvp->tv_usec -= 1000000;
> + }
> +
> +}
> +#endif
> +
> +void
> +dmtimer_delay(u_int usecs)
> +{
> + u_int32_t clock, oclock, delta, delaycnt;
> + volatile int j;
> + int csec, usec;
> +
> + if (usecs > (0x80000000 / (TIMER_FREQUENCY))) {
> + csec = usecs / 10000;
> + usec = usecs % 10000;
> +
> + delaycnt = (TIMER_FREQUENCY / 100) * csec +
> + (TIMER_FREQUENCY / 100) * usec / 10000;
> + } else {
> + delaycnt = TIMER_FREQUENCY * usecs / 1000000;
> + }
> + if (delaycnt <= 1)
> + for (j = 100; j > 0; j--)
> + ;
> +
> + if (dmtimer_ioh1 == 0) {
> + /* BAH */
> + for (; usecs > 0; usecs--)
> + for (j = 100; j > 0; j--)
> + ;
> + return;
> + }
> + oclock = bus_space_read_4(dmtimer_iot, dmtimer_ioh1, DM_TCRR);
> + while (1) {
> + for (j = 100; j > 0; j--)
> + ;
> + clock = bus_space_read_4(dmtimer_iot, dmtimer_ioh1, DM_TCRR);
> + delta = clock - oclock;
> + if (delta > delaycnt)
> + break;
> + }
> +
> +}
> +
> +void
> +dmtimer_setstatclockrate(int newhz)
> +{
> + int minint, statint;
> + int s;
> +
> + s = splclock();
> +
> + statint = ticks_per_second / newhz;
> + /* calculate largest 2^n which is smaller that just over half statint */
> + statvar = 0x40000000; /* really big power of two */
> + minint = statint / 2 + 100;
> + while (statvar > minint)
> + statvar >>= 1;
> +
> + statmin = statint - (statvar >> 1);
> +
> + splx(s);
> +
> + /*
> + * XXX this allows the next stat timer to occur then it switches
> + * to the new frequency. Rather than switching instantly.
> + */
> +}
> +
> +
> +u_int
> +dmtimer_get_timecount(struct timecounter *tc)
> +{
> + return bus_space_read_4(dmtimer_iot, dmtimer_ioh1, DM_TCRR);
> +}
> Index: dev/intc.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/beagle/dev/intc.c,v
> retrieving revision 1.10
> diff -u -p -u -p -r1.10 intc.c
> --- dev/intc.c 10 Nov 2011 19:37:01 -0000 1.10
> +++ dev/intc.c 26 Apr 2013 14:43:24 -0000
> @@ -36,7 +36,7 @@
> #define INTC_SIR_FIQ 0x44 /* R */
> #define INTC_CONTROL 0x48 /* RW */
> #define INTC_CONTROL_NEWIRQ 0x1
> -#define INTC_CONTROL_NEWFIQ 0x1
> +#define INTC_CONTROL_NEWFIQ 0x2
> #define INTC_CONTROL_GLOBALMASK 0x1
> #define INTC_PROTECTION 0x4c /* RW */
> #define INTC_PROTECTION_PROT 1 /* only privileged mode */
> @@ -53,33 +53,6 @@
> #define INTC_PENDING_IRQn(i) 0x80+(0x20*i)+0x18 /* R */
> #define INTC_PENDING_FIQn(i) 0x80+(0x20*i)+0x1c /* R */
>
> -#define INTC_ITR0 0x80 /* R */
> -#define INTC_MIR0 0x84 /* RW */
> -#define INTC_CLEAR0 0x88 /* RW */
> -#define INTC_SET0 0x8c /* RW */
> -#define INTC_ISR_SET0 0x90 /* RW */
> -#define INTC_ISR_CLEAR0 0x94 /* RW */
> -#define INTC_PENDING_IRQ0 0x98 /* R */
> -#define INTC_PENDING_FIQ0 0x9c /* R */
> -
> -#define INTC_ITR1 0xa0 /* R */
> -#define INTC_MIR1 0xa4 /* RW */
> -#define INTC_CLEAR1 0xa8 /* RW */
> -#define INTC_SET1 0xac /* RW */
> -#define INTC_ISR_SET1 0xb0 /* RW */
> -#define INTC_ISR_CLEAR1 0xb4 /* RW */
> -#define INTC_PENDING_IRQ1 0xb8 /* R */
> -#define INTC_PENDING_FIQ1 0xbc /* R */
> -
> -#define INTC_ITR2 0xc0 /* R */
> -#define INTC_MIR2 0xc4 /* RW */
> -#define INTC_CLEAR2 0xc8 /* RW */
> -#define INTC_SET2 0xcc /* RW */
> -#define INTC_ISR_SET2 0xd0 /* RW */
> -#define INTC_ISR_CLEAR2 0xd4 /* RW */
> -#define INTC_PENDING_IRQ2 0xd8 /* R */
> -#define INTC_PENDING_FIQ2 0xdc /* R */
> -
> #define INTC_ILRn(i) 0x100+(4*i)
> #define INTC_ILR_IRQ 0x0 /* not of FIQ */
> #define INTC_ILR_FIQ 0x1
> @@ -112,7 +85,7 @@ volatile int softint_pending;
>
> struct intrq intc_handler[NIRQ];
> u_int32_t intc_smask[NIPL];
> -u_int32_t intc_imask[3][NIPL];
> +u_int32_t intc_imask[INTC_NUM_BANKS][NIPL];
>
> bus_space_tag_t intc_iot;
> bus_space_handle_t intc_ioh;
> @@ -159,9 +132,8 @@ intc_attach(struct device *parent, struc
> /* XXX - check power saving bit */
>
> /* mask all interrupts */
> - bus_space_write_4(intc_iot, intc_ioh, INTC_MIR0, 0xffffffff);
> - bus_space_write_4(intc_iot, intc_ioh, INTC_MIR1, 0xffffffff);
> - bus_space_write_4(intc_iot, intc_ioh, INTC_MIR2, 0xffffffff);
> + for (i = 0; i < INTC_NUM_BANKS; i++)
> + bus_space_write_4(intc_iot, intc_ioh, INTC_MIRn(i), 0xffffffff);
>
> for (i = 0; i < NIRQ; i++) {
> bus_space_write_4(intc_iot, intc_ioh, INTC_ILRn(i),
> @@ -295,7 +267,7 @@ intc_setipl(int new)
> }
> #endif
> ci->ci_cpl = new;
> - for (i = 0; i < 3; i++)
> + for (i = 0; i < INTC_NUM_BANKS; i++)
> bus_space_write_4(intc_iot, intc_ioh,
> INTC_MIRn(i), intc_imask[i][new]);
> bus_space_write_4(intc_iot, intc_ioh, INTC_CONTROL,
> @@ -310,7 +282,7 @@ intc_intr_bootstrap(vaddr_t addr)
> extern struct bus_space armv7_bs_tag;
> intc_iot = &armv7_bs_tag;
> intc_ioh = addr;
> - for (i = 0; i < 3; i++)
> + for (i = 0; i < INTC_NUM_BANKS; i++)
> for (j = 0; j < NIPL; j++)
> intc_imask[i][j] = 0xffffffff;
> }
> Index: dev/intc.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/beagle/dev/intc.h,v
> retrieving revision 1.2
> diff -u -p -u -p -r1.2 intc.h
> --- dev/intc.h 24 Oct 2011 22:49:07 -0000 1.2
> +++ dev/intc.h 26 Apr 2013 14:43:24 -0000
> @@ -36,7 +36,10 @@ int intc_splraise(int ipl);
> int intc_spllower(int ipl);
> void intc_setsoftintr(int si);
>
> -#define INTC_NUM_IRQ 96
> +#ifndef INTC_NUM_IRQ
> + #define INTC_NUM_IRQ 96
> +#endif
> +#define INTC_NUM_BANKS INTC_NUM_IRQ/32
>
> /*
> * An useful function for interrupt handlers.
> Index: dev/omap.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/beagle/dev/omap.c,v
> retrieving revision 1.4
> diff -u -p -u -p -r1.4 omap.c
> --- dev/omap.c 25 Apr 2013 23:07:17 -0000 1.4
> +++ dev/omap.c 26 Apr 2013 14:43:24 -0000
> @@ -66,6 +66,17 @@ struct board_dev beagleboard_devs[] = {
> { NULL, 0 }
> };
>
> +struct board_dev beaglebone_devs[] = {
> + { "prcm", 0 },
> + { "intc", 0 },
> + { "dmtimer", 0 },
> + { "dmtimer", 1 },
> + { "omdog", 0 },
> + { "ommmc", 0 }, /* HSMMC0 */
> + { "com", 0 }, /* UART0 */
> + { NULL, 0 }
> +};
> +
> struct board_dev overo_devs[] = {
> { "prcm", 0 },
> { "intc", 0 },
> @@ -134,6 +145,11 @@ omap_attach(struct device *parent, struc
> printf(": BeagleBoard\n");
> omap3_init();
> board_devs = beagleboard_devs;
> + break;
> + case BOARD_ID_AM335X_BEAGLEBONE:
> + printf(": BeagleBone\n");
> + am335x_init();
> + board_devs = beaglebone_devs;
> break;
> case BOARD_ID_OMAP3_OVERO:
> printf(": Gumstix Overo\n");
> Index: dev/omapvar.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/beagle/dev/omapvar.h,v
> retrieving revision 1.1
> diff -u -p -u -p -r1.1 omapvar.h
> --- dev/omapvar.h 10 Nov 2011 19:37:01 -0000 1.1
> +++ dev/omapvar.h 26 Apr 2013 14:43:24 -0000
> @@ -44,6 +44,7 @@ struct omap_dev *omap_find_dev(const cha
>
> void omap3_init(void);
> void omap4_init(void);
> +void am335x_init(void);
>
> /* XXX */
> void *avic_intr_establish(int irqno, int level, int (*func)(void *),
> @@ -51,6 +52,7 @@ void *avic_intr_establish(int irqno, int
>
> /* board identification - from uboot */
> #define BOARD_ID_OMAP3_BEAGLE 1546
> +#define BOARD_ID_AM335X_BEAGLEBONE 3589
> #define BOARD_ID_OMAP3_OVERO 1798
> #define BOARD_ID_OMAP4_PANDA 2791
> extern uint32_t board_id;
> Index: dev/omdog.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/beagle/dev/omdog.c,v
> retrieving revision 1.5
> diff -u -p -u -p -r1.5 omdog.c
> --- dev/omdog.c 15 Nov 2011 23:01:11 -0000 1.5
> +++ dev/omdog.c 26 Apr 2013 14:43:24 -0000
> @@ -26,7 +26,6 @@
> #include <machine/intr.h>
> #include <machine/bus.h>
> #include <beagle/dev/omapvar.h>
> -#include <beagle/dev/omgpiovar.h>
>
> /* registers */
> #define WIDR 0x00
> @@ -77,7 +76,7 @@ omdog_attach(struct device *parent, stru
> sc->sc_iot = oa->oa_iot;
> if (bus_space_map(sc->sc_iot, oa->oa_dev->mem[0].addr,
> oa->oa_dev->mem[0].size, 0, &sc->sc_ioh))
> - panic("gptimer_attach: bus_space_map failed!");
> + panic("%s: bus_space_map failed!", __func__);
>
> rev = bus_space_read_4(sc->sc_iot, sc->sc_ioh, WIDR);
>
> Index: dev/ommmc.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/beagle/dev/ommmc.c,v
> retrieving revision 1.14
> diff -u -p -u -p -r1.14 ommmc.c
> --- dev/ommmc.c 15 Nov 2011 21:46:44 -0000 1.14
> +++ dev/ommmc.c 26 Apr 2013 14:43:25 -0000
> @@ -39,7 +39,7 @@
> #define MMCHS3_ADDR 0x480AD000
>
> /*
> - * NOTE: on OMAP4430 these registers skew by 0x100
> + * NOTE: on OMAP4430/AM335x these registers skew by 0x100
> * this is handled by mapping at base address + 0x100
> * then all but the REVISION register is 'correctly' mapped.
> */
> @@ -183,8 +183,6 @@
>
> void ommmc_attach(struct device *parent, struct device *self, void *args);
>
> -#include <machine/bus.h>
> -
> struct ommmc_softc {
> struct device sc_dev;
> bus_space_tag_t sc_iot;
> @@ -358,11 +356,12 @@ ommmc_attach(struct device *parent, stru
> struct sdmmcbus_attach_args saa;
> int baseaddr;
> int error = 1;
> + u_int32_t rev;
>
> /* XXX - ICLKEN, FCLKEN? */
>
> baseaddr = oa->oa_dev->mem[0].addr;
> - if (board_id == BOARD_ID_OMAP4_PANDA) {
> + if (board_id == BOARD_ID_OMAP4_PANDA || board_id ==
> BOARD_ID_AM335X_BEAGLEBONE) {
> /* omap4430 has mmc registers offset +0x100, but not revision */
> baseaddr += 0x100;
> }
> @@ -370,9 +369,7 @@ ommmc_attach(struct device *parent, stru
> sc->sc_iot = oa->oa_iot;
> if (bus_space_map(sc->sc_iot, baseaddr, oa->oa_dev->mem[0].size,
> 0, &sc->sc_ioh))
> - panic("omgpio_attach: bus_space_map failed!");
> -
> - printf("\n");
> + panic("%s: bus_space_map failed!", __func__);
>
> /* XXX DMA channels? */
> /* FIXME prcm_enableclock(sc->clockbit); */
> @@ -394,6 +391,10 @@ ommmc_attach(struct device *parent, stru
> * Reset the host controller and enable interrupts.
> */
> (void)ommmc_host_reset(sc);
> +
> + /* read revision */
> + rev = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MMCHS_REV);
> + printf(" rev %d.%d\n", (rev & 0xf0000000) >> 28, (rev & 0x0f000000) >>
> 24);
>
> #if 0
> /* Determine host capabilities. */
> Index: dev/omusbtll.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/beagle/dev/omusbtll.c,v
> retrieving revision 1.4
> diff -u -p -u -p -r1.4 omusbtll.c
> --- dev/omusbtll.c 10 Nov 2011 19:37:01 -0000 1.4
> +++ dev/omusbtll.c 26 Apr 2013 14:43:25 -0000
> @@ -112,7 +112,7 @@ omusbtll_attach(struct device *parent, s
> sc->sc_iot = oa->oa_iot;
> if (bus_space_map(sc->sc_iot, oa->oa_dev->mem[0].addr,
> oa->oa_dev->mem[0].size, 0, &sc->sc_ioh)) {
> - printf("omgpio_attach: bus_space_map failed!\n");
> + printf("%s: bus_space_map failed!\n", __func__);
> return;
> }
>
> Index: dev/prcm.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/beagle/dev/prcm.c,v
> retrieving revision 1.9
> diff -u -p -u -p -r1.9 prcm.c
> --- dev/prcm.c 10 Nov 2011 19:37:01 -0000 1.9
> +++ dev/prcm.c 26 Apr 2013 14:43:25 -0000
> @@ -185,7 +185,10 @@ prcm_attach(struct device *parent, struc
>
> reg = bus_space_read_4(prcm_iot, prcm_ioh, PRCM_REVISION);
> printf(" rev %d.%d\n", reg >> 4 & 0xf, reg & 0xf);
> -
> +
> + if (board_id == BOARD_ID_AM335X_BEAGLEBONE)
> + return;
> +
> /* Setup the 120MHZ DPLL5 clock, to be used by USB. */
> prcm_setup_dpll5();
>
> @@ -241,31 +244,55 @@ prcm_attach(struct device *parent, struc
> void
> prcm_setclock(int clock, int speed)
> {
> -#if 1
> u_int32_t oreg, reg, mask;
> - if (clock == 1) {
> - oreg = bus_space_read_4(prcm_iot, prcm_ioh, CM_CLKSEL_WKUP);
> - mask = 1;
> - reg = (oreg &~mask) | (speed & mask);
> - printf(" prcm_setclock old %08x new %08x", oreg, reg );
> - bus_space_write_4(prcm_iot, prcm_ioh, CM_CLKSEL_WKUP, reg);
> - } else if (clock >= 2 && clock <= 9) {
> - int shift = (clock-2);
> - oreg = bus_space_read_4(prcm_iot, prcm_ioh, CM_CLKSEL_PER);
> -
> - mask = 1 << (mask);
> - reg = (oreg & ~mask) | ( (speed << shift) & mask);
> - printf(" prcm_setclock old %08x new %08x", oreg, reg);
> -
> - bus_space_write_4(prcm_iot, prcm_ioh, CM_CLKSEL_PER, reg);
> - } else
> - panic("prcm_setclock invalid clock %d", clock);
> -#endif
> +
> + if (board_id == BOARD_ID_AM335X_BEAGLEBONE) {
> + /* set CLKSEL register */
> + if (clock == 1) {
> + /* for timer 2 */
> + oreg = bus_space_read_4(prcm_iot, prcm_ioh,
> + AM335X_PRCM_CM_DPLL_CLKSEL_TIMER2_CLK);
> + mask = 3;
> + reg = oreg & ~mask;
> + reg |=0x02;
> + bus_space_write_4(prcm_iot, prcm_ioh,
> + AM335X_PRCM_CM_DPLL_CLKSEL_TIMER2_CLK, reg);
> + } else if (clock == 2) {
> + /* for timer 3 */
> + oreg = bus_space_read_4(prcm_iot, prcm_ioh,
> + AM335X_PRCM_CM_DPLL_CLKSEL_TIMER3_CLK);
> + mask = 3;
> + reg = oreg & ~mask;
> + reg |=0x02;
> + bus_space_write_4(prcm_iot, prcm_ioh,
> + AM335X_PRCM_CM_DPLL_CLKSEL_TIMER3_CLK, reg);
> + }
> + } else {
> + if (clock == 1) {
> + oreg = bus_space_read_4(prcm_iot, prcm_ioh,
> CM_CLKSEL_WKUP);
> + mask = 1;
> + reg = (oreg &~mask) | (speed & mask);
> + printf(" prcm_setclock old %08x new %08x", oreg, reg );
> + bus_space_write_4(prcm_iot, prcm_ioh, CM_CLKSEL_WKUP,
> reg);
> + } else if (clock >= 2 && clock <= 9) {
> + int shift = (clock-2);
> + oreg = bus_space_read_4(prcm_iot, prcm_ioh,
> CM_CLKSEL_PER);
> +
> + mask = 1 << (shift);
> + reg = (oreg & ~mask) | ( (speed << shift) & mask);
> + printf(" prcm_setclock old %08x new %08x", oreg, reg);
> +
> + bus_space_write_4(prcm_iot, prcm_ioh, CM_CLKSEL_PER,
> reg);
> + } else
> + panic("prcm_setclock invalid clock %d", clock);
> + }
> }
>
> void
> prcm_enableclock(int bit)
> {
> + if (board_id == BOARD_ID_AM335X_BEAGLEBONE)
> + return;
> u_int32_t fclk, iclk, fmask, imask, mbit;
> int freg, ireg, reg;
> printf("prcm_enableclock %d:", bit);
> @@ -297,6 +324,29 @@ prcm_enableclock(int bit)
> }
> printf ("\n");
> }
> +
> +void
> +prcm_enablemodule(uint32_t reg)
> +{
> + uint32_t clkctrl;
> +
> + switch (board_id) {
> + case BOARD_ID_AM335X_BEAGLEBONE:
> + /*set enable bits in CLKCTRL register */
> + clkctrl = bus_space_read_4(prcm_iot, prcm_ioh, reg);
> + clkctrl &=~AM335X_CLKCTRL_MODULEMODE_MASK;
> + clkctrl |= AM335X_CLKCTRL_MODULEMODE_ENABLE;
> + bus_space_write_4(prcm_iot, prcm_ioh, reg, clkctrl);
> + /* wait until module is enabled */
> + while (bus_space_read_4(prcm_iot, prcm_ioh, reg) & 0x30000)
> + ;
> + break;
> + default:
> + /* ??? */
> + break;
> + }
> +}
> +
>
> /*
> * OMAP35xx Power, Reset, and Clock Management Reference Guide
> Index: dev/prcmvar.h
> ===================================================================
> RCS file: /cvs/src/sys/arch/beagle/dev/prcmvar.h,v
> retrieving revision 1.4
> diff -u -p -u -p -r1.4 prcmvar.h
> --- dev/prcmvar.h 13 Feb 2010 06:03:37 -0000 1.4
> +++ dev/prcmvar.h 26 Apr 2013 14:43:25 -0000
> @@ -20,6 +20,35 @@ void prcm_setclock(int clock, int speed)
> #define PRCM_CLK_SPEED_SYS 1
>
> void prcm_enableclock(int bit);
> +void prcm_enablemodule(uint32_t reg);
> +
> +#define AM335X_CLKCTRL_MODULEMODE_ENABLE 2
> +#define AM335X_CLKCTRL_MODULEMODE_DISABLE 0
> +#define AM335X_CLKCTRL_MODULEMODE_MASK 0x00000003
> +
> +#define AM335X_PRCM_CM_PER 0x0000
> +#define AM335X_PRCM_CM_PER_MMC0_CLKCTRL 0x003c
> +#define AM335X_PRCM_CM_PER_TIMER2_CLKCTRL 0x0080
> +#define AM335X_PRCM_CM_PER_TIMER3_CLKCTRL 0x0084
> +#define AM335X_PRCM_CM_WKUP 0x0400
> +#define AM335X_PRCM_CM_WKUP_TIMER0_CLKCTRL 0x0410
> +#define AM335X_PRCM_CM_DPLL 0x0500
> +#define AM335X_PRCM_CM_DPLL_CLKSEL_TIMER2_CLK 0x0508
> +#define AM335X_PRCM_CM_DPLL_CLKSEL_TIMER3_CLK 0x050c
> +#define AM335X_PRCM_CM_MPU 0x0600
> +#define AM335X_PRCM_CM_DEVICE 0x0700
> +#define AM335X_PRCM_CM_RTC 0x0800
> +#define AM335X_PRCM_CM_GFX 0x0900
> +#define AM335X_PRCM_CM_CEFUSE 0x0a00
> +
> +#define AM335X_PRCM_PRM_IRQ 0x0b00
> +#define AM335X_PRCM_PRM_PER 0x0c00
> +#define AM335X_PRCM_PRM_WKUP 0x0d00
> +#define AM335X_PRCM_PRM_MPU 0x0e00
> +#define AM335X_PRCM_PRM_DEVICE 0x0f00
> +#define AM335X_PRCM_PRM_RTC 0x1000
> +#define AM335X_PRCM_PRM_GFX 0x1100
> +#define AM335X_PRCM_PRM_CEFUSE 0x1200
>
> #define CM_FCLKEN1_CORE 0x0a00
> #define CM_FCLKEN1_CORE_MSK 0x41fffe00
> Index: pmap.c
> ===================================================================
> RCS file: /cvs/src/sys/arch/arm/arm/pmap.c,v
> retrieving revision 1.38
> diff -u -p -u -p -r1.38 pmap.c
> --- pmap.c 5 Dec 2012 23:20:11 -0000 1.38
> +++ pmap.c 26 Apr 2013 14:42:58 -0000
> @@ -2607,7 +2607,6 @@ pmap_protect(pmap_t pm, vaddr_t sva, vad
> * OK, at this point, we know we're doing write-protect operation.
> * If the pmap is active, write-back the range.
> */
> - pmap_dcache_wb_range(pm, sva, eva - sva, FALSE, FALSE);
>
> flush = ((eva - sva) >= (PAGE_SIZE * 4)) ? 0 : -1;
> flags = 0;
> @@ -2629,6 +2628,9 @@ pmap_protect(pmap_t pm, vaddr_t sva, vad
> if ((pte = *ptep) != 0 && (pte & L2_S_PROT_W) != 0) {
> struct vm_page *pg;
> u_int f;
> +
> + pmap_dcache_wb_range(pm, sva, PAGE_SIZE, FALSE,
> + FALSE);
>
> pg = PHYS_TO_VM_PAGE(l2pte_pa(pte));
> pte &= ~L2_S_PROT_W;
>
>