Skip to content

Commit

Permalink
Add cpufreq driver
Browse files Browse the repository at this point in the history
  • Loading branch information
popcornmix committed Oct 8, 2012
1 parent ce1249d commit 996a468
Show file tree
Hide file tree
Showing 8 changed files with 381 additions and 37 deletions.
1 change: 1 addition & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,7 @@ config ARCH_BCM2708
select HAVE_SCHED_CLOCK
select NEED_MACH_MEMORY_H
select CLKDEV_LOOKUP
select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select ARM_ERRATA_411920
select MACH_BCM2708
Expand Down
6 changes: 6 additions & 0 deletions arch/arm/configs/bcmrpi_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext3 rootwait"
CONFIG_KEXEC=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=m
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_IDLE=y
CONFIG_VFP=y
CONFIG_BINFMT_MISC=m
Expand Down
81 changes: 73 additions & 8 deletions arch/arm/mach-bcm2708/include/mach/vcio.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,82 @@
#define BCM_VCIO_DRIVER_NAME "bcm2708_vcio"

/* Constants shared with the ARM identifying separate mailbox channels */
#define MBOX_CHAN_POWER 0 /* for use by the power management interface */
#define MBOX_CHAN_FB 1 /* for use by the frame buffer */
#define MBOX_CHAN_VUART 2 /* for use by the virtual UART */
#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */
#define MBOX_CHAN_LEDS 4 /* for use by the leds interface */
#define MBOX_CHAN_BUTTONS 5 /* for use by the buttons interface */
#define MBOX_CHAN_TOUCH 6 /* for use by the touchscreen interface */
#define MBOX_CHAN_POWER 0 /* for use by the power management interface */
#define MBOX_CHAN_FB 1 /* for use by the frame buffer */
#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */
#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */
#define MBOX_CHAN_COUNT 9
#define MBOX_CHAN_COUNT 9

/* Mailbox property tags */
enum {
VCMSG_PROPERTY_END = 0x00000000,
VCMSG_GET_FIRMWARE_REVISION = 0x00000001,
VCMSG_GET_BOARD_MODEL = 0x00010001,
VCMSG_GET_BOARD_REVISION = 0x00020002,
VCMSG_GET_BOARD_MAC_ADDRESS = 0x00020003,
VCMSG_GET_BOARD_SERIAL = 0x00020004,
VCMSG_GET_ARM_MEMORY = 0x00020005,
VCMSG_GET_VC_MEMORY = 0x00020006,
VCMSG_GET_CLOCKS = 0x00020007,
VCMSG_GET_COMMAND_LINE = 0x00050001,
VCMSG_GET_DMA_CHANNELS = 0x00060001,
VCMSG_GET_POWER_STATE = 0x00020001,
VCMSG_GET_TIMING = 0x00020002,
VCMSG_SET_POWER_STATE = 0x00028001,
VCMSG_GET_CLOCK_STATE = 0x00030001,
VCMSG_SET_CLOCK_STATE = 0x00038001,
VCMSG_GET_CLOCK_RATE = 0x00030002,
VCMSG_SET_CLOCK_RATE = 0x00038002,
VCMSG_GET_VOLTAGE = 0x00030003,
VCMSG_SET_VOLTAGE = 0x00038003,
VCMSG_GET_MAX_CLOCK = 0x00030004,
VCMSG_GET_MAX_VOLTAGE = 0x00030005,
VCMSG_GET_TEMPERATURE = 0x00030006,
VCMSG_GET_MIN_CLOCK = 0x00030007,
VCMSG_GET_MIN_VOLTAGE = 0x00030008,
VCMSG_GET_TURBO = 0x00030009,
VCMSG_SET_TURBO = 0x00038009,
VCMSG_SET_ALLOCATE_BUFFER = 0x00040001,
VCMSG_SET_RELEASE_BUFFER = 0x00048001,
VCMSG_SET_BLANK_SCREEN = 0x00040002,
VCMSG_TST_BLANK_SCREEN = 0x00044002,
VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003,
VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003,
VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003,
VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004,
VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004,
VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004,
VCMSG_GET_DEPTH = 0x00040005,
VCMSG_TST_DEPTH = 0x00044005,
VCMSG_SET_DEPTH = 0x00048005,
VCMSG_GET_PIXEL_ORDER = 0x00040006,
VCMSG_TST_PIXEL_ORDER = 0x00044006,
VCMSG_SET_PIXEL_ORDER = 0x00048006,
VCMSG_GET_ALPHA_MODE = 0x00040007,
VCMSG_TST_ALPHA_MODE = 0x00044007,
VCMSG_SET_ALPHA_MODE = 0x00048007,
VCMSG_GET_PITCH = 0x00040008,
VCMSG_TST_PITCH = 0x00044008,
VCMSG_SET_PITCH = 0x00048008,
VCMSG_GET_VIRTUAL_OFFSET = 0x00040009,
VCMSG_TST_VIRTUAL_OFFSET = 0x00044009,
VCMSG_SET_VIRTUAL_OFFSET = 0x00048009,
VCMSG_GET_OVERSCAN = 0x0004000a,
VCMSG_TST_OVERSCAN = 0x0004400a,
VCMSG_SET_OVERSCAN = 0x0004800a,
VCMSG_GET_PALETTE = 0x0004000b,
VCMSG_TST_PALETTE = 0x0004400b,
VCMSG_SET_PALETTE = 0x0004800b,
VCMSG_GET_LAYER = 0x0004000c,
VCMSG_TST_LAYER = 0x0004400c,
VCMSG_SET_LAYER = 0x0004800c,
VCMSG_GET_TRANSFORM = 0x0004000d,
VCMSG_TST_TRANSFORM = 0x0004400d,
VCMSG_SET_TRANSFORM = 0x0004800d,
};

extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28);
extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28);
extern int /*rc*/ bcm_mailbox_property(void *data, int size);

#endif
47 changes: 18 additions & 29 deletions arch/arm/mach-bcm2708/vc_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,44 +128,33 @@ struct vc_set_msg {
uint32_t end_tag; /* an end identifier, should be set to NULL */
};

#define VCMSG_GET_ARM_MEMORY 0x00010005
#define VCMSG_GET_VC_MEMORY 0x00010006

static void vc_mem_update(void)
{
uint32_t success;
dma_addr_t vc_mem; /* the memory address accessed from videocore */
struct vc_set_msg *get_mem; /* the memory address accessed from driver */

/* allocate some memory for the messages to use throughout the lifetime of the driver, use the larger of the two message structures */
get_mem = (struct vc_set_msg *)dma_alloc_coherent(NULL, PAGE_ALIGN(sizeof(struct vc_set_msg)), &vc_mem, GFP_ATOMIC);
/* clear any garbage */
memset(get_mem, 0, sizeof(struct vc_set_msg));
struct vc_set_msg msg; /* the memory address accessed from driver */
uint32_t s;

memset(&msg, 0, sizeof msg);
/* create the message */
get_mem->msg_size = sizeof(struct vc_set_msg);
get_mem->tag[0].tag_id = VCMSG_GET_VC_MEMORY;
get_mem->tag[0].buffer_size = 8;
get_mem->tag[0].data_size = 0;
get_mem->tag[1].tag_id = VCMSG_GET_ARM_MEMORY;
get_mem->tag[1].buffer_size = 8;
get_mem->tag[1].data_size = 0;
msg.msg_size = sizeof msg;
msg.tag[0].tag_id = VCMSG_GET_VC_MEMORY;
msg.tag[0].buffer_size = 8;
msg.tag[0].data_size = 0;
msg.tag[1].tag_id = VCMSG_GET_ARM_MEMORY;
msg.tag[1].buffer_size = 8;
msg.tag[1].data_size = 0;

/* send the message */
wmb();
bcm_mailbox_write(MBOX_CHAN_PROPERTY,(uint32_t)vc_mem);
bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success);
rmb();
s = bcm_mailbox_property(&msg, sizeof msg);

LOG_DBG("%s: resp %x, vcbase=%x vcsize=%x armbase=%x armsize=%x", __func__, get_mem->request_code,
get_mem->tag[0].base, get_mem->tag[0].size, get_mem->tag[1].base, get_mem->tag[1].size);
LOG_DBG("%s: success=%d resp %x, vcbase=%x vcsize=%x armbase=%x armsize=%x", __func__, s, msg.request_code,
msg.tag[0].base, msg.tag[0].size, msg.tag[1].base, msg.tag[1].size);

/* check we're all good */
if (get_mem->request_code & 0x80000000) {
mm_vc_mem_base = get_mem->tag[0].base;
mm_vc_mem_size = get_mem->tag[0].size+get_mem->tag[1].size;
mm_vc_mem_phys_addr = get_mem->tag[1].base;
if (s == 0 && msg.request_code & 0x80000000) {
mm_vc_mem_base = msg.tag[0].base;
mm_vc_mem_size = msg.tag[0].size+msg.tag[1].size;
mm_vc_mem_phys_addr = msg.tag[1].base;
}
dma_free_coherent(NULL, PAGE_ALIGN(sizeof(struct vc_set_msg)), (void *)get_mem, vc_mem);
}


Expand Down
34 changes: 34 additions & 0 deletions arch/arm/mach-bcm2708/vcio.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,40 @@ static void dev_mbox_register(const char *dev_name, struct device *dev)
mbox_dev = dev;
}

extern int bcm_mailbox_property(void *data, int size)
{
uint32_t success;
dma_addr_t mem_bus; /* the memory address accessed from videocore */
void *mem_kern; /* the memory address accessed from driver */
int s = 0;

/* allocate some memory for the messages communicating with GPU */
mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, GFP_ATOMIC);
if (mem_kern) {
/* create the message */
memcpy(mem_kern, data, size);

/* send the message */
wmb();
s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus);
if (s == 0) {
s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success);
}
if (s == 0) {
/* copy the response */
rmb();
memcpy(data, mem_kern, size);
}
dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus);
} else {
s = -ENOMEM;
}
if (s != 0)
printk(KERN_ERR DRIVER_NAME ": %s failed (%d)\n", __func__, s);
return s;
}
EXPORT_SYMBOL_GPL(bcm_mailbox_property);

/* ----------------------------------------------------------------------
* Platform Device for Mailbox
* -------------------------------------------------------------------- */
Expand Down
9 changes: 9 additions & 0 deletions drivers/cpufreq/Kconfig.arm
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,12 @@ config ARM_EXYNOS5250_CPUFREQ
help
This adds the CPUFreq driver for Samsung EXYNOS5250
SoC.

config ARM_BCM2835_CPUFREQ
bool "BCM2835 Driver"
default y
help
This adds the CPUFreq driver for BCM2835

If in doubt, say N.

1 change: 1 addition & 0 deletions drivers/cpufreq/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ) += exynos4x12-cpufreq.o
obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ) += exynos5250-cpufreq.o
obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
obj-$(CONFIG_ARM_BCM2835_CPUFREQ) += bcm2835-cpufreq.o

##################################################################################
# PowerPC platform drivers
Expand Down
Loading

0 comments on commit 996a468

Please sign in to comment.