static uint32_t bcm2835_cpufreq_get_clock(int tag) { int s; int arm_rate = 0; struct vc_msg msg; /* wipe all previous message data */ memset(&msg, 0, sizeof msg); msg.msg_size = sizeof msg; msg.tag.tag_id = tag; msg.tag.buffer_size = 8; msg.tag.data_size = 4; /* we're just sending the clock ID which is one word long */ msg.tag.dev_id = VCMSG_ID_ARM_CLOCK; /* send the message */ s = bcm_mailbox_property(&msg, sizeof msg); /* check if it was all ok and return the rate in KHz */ if (s == 0 && (msg.request_code & 0x80000000)) arm_rate = msg.tag.val/1000; print_debug("%s frequency = %d\n", tag == VCMSG_GET_CLOCK_RATE ? "Current": tag == VCMSG_GET_MIN_CLOCK ? "Min": tag == VCMSG_GET_MAX_CLOCK ? "Max": "Unexpected", arm_rate); return arm_rate; }
/* --- FUNCTIONS --- */ static int bcm2835_get_max_temp(struct thermal_zone_device *thermal_dev, int trip_num, unsigned long *temp) { int result; print_debug("IN"); /* wipe all previous message data */ memset(&bcm2835_data.msg, 0, sizeof bcm2835_data.msg); /* prepare message */ bcm2835_data.msg.msg_size = sizeof bcm2835_data.msg; bcm2835_data.msg.tag.buffer_size = 8; bcm2835_data.msg.tag.tag_id = VC_TAG_GET_MAX_TEMP; /* send the message */ result = bcm_mailbox_property(&bcm2835_data.msg, sizeof bcm2835_data.msg); /* check if it was all ok and return the rate in milli degrees C */ if (result == 0 && (bcm2835_data.msg.request_code & 0x80000000)) *temp = (uint)bcm2835_data.msg.tag.val; #ifdef THERMAL_DEBUG_ENABLE else print_debug("Failed to get temperature!"); #endif print_debug("Got temperature as %u",(uint)*temp); print_debug("OUT"); return 0; }
/****** VC MAILBOX FUNCTIONALITY ******/ unsigned int AllocateVcMemory(unsigned int *pHandle, unsigned int size, unsigned int alignment, unsigned int flags) { struct vc_msg { unsigned int m_msgSize; unsigned int m_response; struct vc_tag { unsigned int m_tagId; unsigned int m_sendBufferSize; union { unsigned int m_sendDataSize; unsigned int m_recvDataSize; }; struct args { union { unsigned int m_size; unsigned int m_handle; }; unsigned int m_alignment; unsigned int m_flags; } m_args; } m_tag; unsigned int m_endTag; } msg; int s; msg.m_msgSize = sizeof(msg); msg.m_response = 0; msg.m_endTag = 0; //fill in the tag for the allocation command msg.m_tag.m_tagId = 0x3000c; msg.m_tag.m_sendBufferSize = 12; msg.m_tag.m_sendDataSize = 12; //fill in our args msg.m_tag.m_args.m_size = size; msg.m_tag.m_args.m_alignment = alignment; msg.m_tag.m_args.m_flags = flags; //run the command s = bcm_mailbox_property(&msg, sizeof(msg)); if (s == 0 && msg.m_response == 0x80000000 && msg.m_tag.m_recvDataSize == 0x80000004) { *pHandle = msg.m_tag.m_args.m_handle; return 0; } else { printk(KERN_ERR "failed to allocate vc memory: s=%d response=%08x recv data size=%08x\n", s, msg.m_response, msg.m_tag.m_recvDataSize); return 1; } }
/* =============================================== clk_rate either gets or sets the clock rates. =============================================== */ static uint32_t bcm2835_cpufreq_set_clock(int cur_rate, int arm_rate) { int s, actual_rate=0; struct vc_msg msg; /* wipe all previous message data */ memset(&msg, 0, sizeof msg); msg.msg_size = sizeof msg; msg.tag.tag_id = VCMSG_SET_CLOCK_RATE; msg.tag.buffer_size = 8; msg.tag.data_size = 8; /* we're sending the clock ID and the new rates which is a total of 2 words */ msg.tag.dev_id = VCMSG_ID_ARM_CLOCK; msg.tag.val = arm_rate * 1000; /* send the message */ s = bcm_mailbox_property(&msg, sizeof msg); /* check if it was all ok and return the rate in KHz */ if (s == 0 && (msg.request_code & 0x80000000)) actual_rate = msg.tag.val/1000; print_debug("Setting new frequency = %d -> %d (actual %d)\n", cur_rate, arm_rate, actual_rate); return actual_rate; }
unsigned int LockVcMemory(unsigned int *pBusAddress, unsigned int handle) { struct vc_msg { unsigned int m_msgSize; unsigned int m_response; struct vc_tag { unsigned int m_tagId; unsigned int m_sendBufferSize; union { unsigned int m_sendDataSize; unsigned int m_recvDataSize; }; struct args { union { unsigned int m_handle; unsigned int m_busAddress; }; } m_args; } m_tag; unsigned int m_endTag; } msg; int s; msg.m_msgSize = sizeof(msg); msg.m_response = 0; msg.m_endTag = 0; //fill in the tag for the lock command msg.m_tag.m_tagId = 0x3000d; msg.m_tag.m_sendBufferSize = 4; msg.m_tag.m_sendDataSize = 4; //pass across the handle msg.m_tag.m_args.m_handle = handle; s = bcm_mailbox_property(&msg, sizeof(msg)); if (s == 0 && msg.m_response == 0x80000000 && msg.m_tag.m_recvDataSize == 0x80000004) { //pick out the bus address *pBusAddress = msg.m_tag.m_args.m_busAddress; return 0; } else { printk(KERN_ERR "failed to lock vc memory: s=%d response=%08x recv data size=%08x\n", s, msg.m_response, msg.m_tag.m_recvDataSize); return 1; } }
unsigned int UnlockVcMemory(unsigned int handle) { struct vc_msg { unsigned int m_msgSize; unsigned int m_response; struct vc_tag { unsigned int m_tagId; unsigned int m_sendBufferSize; union { unsigned int m_sendDataSize; unsigned int m_recvDataSize; }; struct args { union { unsigned int m_handle; unsigned int m_error; }; } m_args; } m_tag; unsigned int m_endTag; } msg; int s; msg.m_msgSize = sizeof(msg); msg.m_response = 0; msg.m_endTag = 0; //fill in the tag for the unlock command msg.m_tag.m_tagId = 0x3000e; msg.m_tag.m_sendBufferSize = 4; msg.m_tag.m_sendDataSize = 4; //pass across the handle msg.m_tag.m_args.m_handle = handle; s = bcm_mailbox_property(&msg, sizeof(msg)); //check the error code too if (s == 0 && msg.m_response == 0x80000000 && msg.m_tag.m_recvDataSize == 0x80000004 && msg.m_tag.m_args.m_error == 0) return 0; else { printk(KERN_ERR "failed to unlock vc memory: s=%d response=%08x recv data size=%08x error%08x\n", s, msg.m_response, msg.m_tag.m_recvDataSize, msg.m_tag.m_args.m_error); return 1; } }
static int qpu_enable(unsigned int enable) { int i = 1,ret; unsigned int message[32]; message[i++] = 0; // request message[i++] = 0x30012; // set qpu enabled tag message[i++] = 4; // size of buffer message[i++] = 4; // size of data message[i++] = enable; message[i++] = 0; // end tag message[0] = i * sizeof(unsigned int); bcm_mailbox_property(message,i*sizeof(unsigned int)); ret = message[5]; return ret; }
static ssize_t bcm2835_get_temp(struct device *dev, struct device_attribute *attr, char *buf) { struct vc_msg msg; int result; uint temp = 0; int index = ((struct sensor_device_attribute*)to_sensor_dev_attr(attr))->index; print_debug("IN"); /* wipe all previous message data */ memset(&msg, 0, sizeof msg); /* determine the message type */ if(index == TEMP) msg.tag.tag_id = VC_TAG_GET_TEMP; else if (index == MAX_TEMP) msg.tag.tag_id = VC_TAG_GET_MAX_TEMP; else { print_debug("Unknown temperature message!"); return -EINVAL; } msg.msg_size = sizeof msg; msg.tag.buffer_size = 8; /* send the message */ result = bcm_mailbox_property(&msg, sizeof msg); /* check if it was all ok and return the rate in milli degrees C */ if (result == 0 && (msg.request_code & 0x80000000)) temp = (uint)msg.tag.val; #ifdef HWMON_DEBUG_ENABLE else print_debug("Failed to get temperature!"); #endif print_debug("Got temperature as %u",temp); print_debug("OUT"); return sprintf(buf, "%u\n", temp); }
unsigned int ExecuteVcCode(unsigned int code, unsigned int r0, unsigned int r1, unsigned int r2, unsigned int r3, unsigned int r4, unsigned int r5) { struct vc_msg { unsigned int m_msgSize; unsigned int m_response; struct vc_tag { unsigned int m_tagId; unsigned int m_sendBufferSize; union { unsigned int m_sendDataSize; unsigned int m_recvDataSize; }; struct args { union { unsigned int m_pCode; unsigned int m_return; }; unsigned int m_r0; unsigned int m_r1; unsigned int m_r2; unsigned int m_r3; unsigned int m_r4; unsigned int m_r5; } m_args; } m_tag; unsigned int m_endTag; } msg; int s; msg.m_msgSize = sizeof(msg); msg.m_response = 0; msg.m_endTag = 0; //fill in the tag for the unlock command msg.m_tag.m_tagId = 0x30010; msg.m_tag.m_sendBufferSize = 28; msg.m_tag.m_sendDataSize = 28; //pass across the handle msg.m_tag.m_args.m_pCode = code; msg.m_tag.m_args.m_r0 = r0; msg.m_tag.m_args.m_r1 = r1; msg.m_tag.m_args.m_r2 = r2; msg.m_tag.m_args.m_r3 = r3; msg.m_tag.m_args.m_r4 = r4; msg.m_tag.m_args.m_r5 = r5; s = bcm_mailbox_property(&msg, sizeof(msg)); //check the error code too if (s == 0 && msg.m_response == 0x80000000 && msg.m_tag.m_recvDataSize == 0x80000004) return msg.m_tag.m_args.m_return; else { printk(KERN_ERR "failed to execute: s=%d response=%08x recv data size=%08x\n", s, msg.m_response, msg.m_tag.m_recvDataSize); return 1; } }