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;
}
Esempio n. 2
0
/* --- 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;
}
Esempio n. 3
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;
}
Esempio n. 5
0
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;
	}
}
Esempio n. 6
0
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;
	}
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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;
	}
}