Exemplo n.º 1
0
static ssize_t arisc_p2wi_write_block_data_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	ssize_t size = 0;
	u32 ret = 0;

	if ((block_cfg.addr == NULL) || (block_cfg.data == NULL) ||
		(*block_cfg.addr < 0) || (*block_cfg.addr > 0xff)) {
		ARISC_WRN("invalid p2wi paras, regaddr:0x%x, data:0x%x\n", block_cfg.addr ? *block_cfg.addr : 0, block_cfg.data ? *block_cfg.data : 0);
		ARISC_LOG("pls echo like that: echo regaddr data > p2wi_write_block_data\n");
		return size;
	}

	block_cfg.msgattr = ARISC_MESSAGE_ATTR_SOFTSYN;
	block_cfg.len = 1;
	block_cfg.addr = &regaddr;
	block_cfg.data = &data;
	ret = arisc_p2wi_read_block_data(&block_cfg);
	if (ret) {
		ARISC_WRN("p2wi read data:0x%x from regaddr:0x%x fail\n", *block_cfg.data, *block_cfg.addr);
	} else {
		ARISC_LOG("p2wi read data:0x%x from regaddr:0x%x success\n", *block_cfg.data, *block_cfg.addr);
	}
	size = sprintf(buf, "%x\n", data);

	return size;
}
Exemplo n.º 2
0
int sunxi_arisc_wait_ready(void)
{
	ARISC_INF("wait arisc ready....\n");
	if (arisc_wait_ready(10000)) {
		ARISC_LOG("arisc startup failed\n");
	}
	arisc_set_paras();
	ARISC_LOG("sunxi-arisc driver v%s startup ok\n", DRV_VERSION);
	return 0;
}
Exemplo n.º 3
0
static ssize_t arisc_p2wi_write_block_data_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	u32 ret;

	sscanf(buf, "%x %x", (u32 *)&regaddr, (u32 *)&data);
	if ((regaddr < 0) || (regaddr > 0xff)) {
		ARISC_WRN("invalid p2wi paras, regaddr:0x%x, data:0x%x\n", regaddr, data);
		ARISC_WRN("pls echo like that: echo regaddr data > p2wi_write_block_data\n");
		return size;
	}

	block_cfg.msgattr = ARISC_MESSAGE_ATTR_SOFTSYN;
	block_cfg.len = 1;
	block_cfg.addr = &regaddr;
	block_cfg.data = &data;
	ret = arisc_p2wi_write_block_data(&block_cfg);
	if (ret) {
		ARISC_WRN("p2wi write data:0x%x to regaddr:0x%x fail\n", *block_cfg.data, *block_cfg.addr);
	} else {
		ARISC_LOG("p2wi write data:0x%x to regaddr:0x%x success\n", *block_cfg.data, *block_cfg.addr);
	}

	return size;
}
Exemplo n.º 4
0
static ssize_t arisc_rsb_write_block_data_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	u32 ret = 0;

	sscanf(buf, "%x %x %x %x", &devaddr, (u32 *)&regaddr, (u32 *)&data, &datatype);
	if ((devaddr > 0xff) ||
	((datatype !=  RSB_DATA_TYPE_BYTE) && (datatype !=  RSB_DATA_TYPE_HWORD) && (datatype !=  RSB_DATA_TYPE_WORD))) {
		ARISC_WRN("invalid rsb paras, devaddr:0x%x, regaddr:0x%x, data:0x%x, datatype:0x%x\n", devaddr, regaddr, data, datatype);
		ARISC_WRN("pls echo like that: echo devaddr regaddr data datatype > rsb_write_block_data\n");
		return size;
	}

	block_cfg.msgattr = ARISC_MESSAGE_ATTR_SOFTSYN;
	block_cfg.datatype = datatype;
	block_cfg.len = 1;
	block_cfg.devaddr = devaddr;
	block_cfg.regaddr = &regaddr;
	block_cfg.data = &data;
	ret = arisc_rsb_write_block_data(&block_cfg);
	if (ret) {
		ARISC_ERR("rsb write data:0x%x to devaddr:0x%x regaddr:0x%x fail\n", *block_cfg.data, block_cfg.devaddr, *block_cfg.regaddr);
	} else {
		ARISC_LOG("rsb write data:0x%x to devaddr:0x%x regaddr:0x%x success\n", *block_cfg.data, block_cfg.devaddr, *block_cfg.regaddr);
	}

	return size;
}
Exemplo n.º 5
0
static int sunxi_arisc_para_init(struct arisc_para *para)
{
	/* init para */
	memset(para, 0, sizeof(struct arisc_para));
	para->message_pool_phys = (uint32_t)dts_cfg.space.msgpool_dst;
	para->message_pool_size = (uint32_t)dts_cfg.space.msgpool_size;
	para->standby_base = (uint32_t)dts_cfg.space.standby_dst;
	para->standby_size = (uint32_t)dts_cfg.space.standby_size;
	memcpy((void *)&para->vf, (void *)dts_cfg.vf, sizeof(para->vf));
	memcpy((void *)&para->dram_para, (void *)&dts_cfg.dram_para, sizeof(para->dram_para));
	para->power_key_code = dts_cfg.s_cir.power_key_code;
	para->addr_code = dts_cfg.s_cir.addr_code;
	para->suart_status = dts_cfg.s_uart.status;
	para->pmu_bat_shutdown_ltf = dts_cfg.pmu.pmu_bat_shutdown_ltf;
	para->pmu_bat_shutdown_htf = dts_cfg.pmu.pmu_bat_shutdown_htf;
	para->pmu_pwroff_vol = dts_cfg.pmu.pmu_pwroff_vol;
	para->power_start = dts_cfg.pmu.power_start;
	para->powchk_used = dts_cfg.power.powchk_used;
	para->power_reg = dts_cfg.power.power_reg;
	para->system_power = dts_cfg.power.system_power;

	ARISC_LOG("arisc_para size:%llx\n", sizeof(struct arisc_para));
	ARISC_INF("msgpool base:%x, size:%u\n", para->message_pool_phys,
		para->message_pool_size);

	return 0;
}
Exemplo n.º 6
0
static ssize_t arisc_dram_crc_paras_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	u32 dram_crc_en      = 0;
	u32 dram_crc_srcaddr = 0;
	u32 dram_crc_len     = 0;

	sscanf(buf, "%x %x %x\n", &dram_crc_en, &dram_crc_srcaddr, &dram_crc_len);

	if ((dram_crc_en != 0) && (dram_crc_en != 1)) {
		ARISC_WRN("invalid arisc debug dram crc paras [%x] [%x] [%x] to set\n",
								  dram_crc_en, dram_crc_srcaddr, dram_crc_len);

		return size;
	}

	arisc_debug_dram_crc_en = dram_crc_en;
	arisc_debug_dram_crc_srcaddr = dram_crc_srcaddr;
	arisc_debug_dram_crc_len = dram_crc_len;
	arisc_set_dram_crc_paras(arisc_debug_dram_crc_en,
							 arisc_debug_dram_crc_srcaddr,
							 arisc_debug_dram_crc_len);
	ARISC_LOG("dram_crc_en=0x%x, dram_crc_srcaddr=0x%x, dram_crc_len=0x%x\n",
			  arisc_debug_dram_crc_en, arisc_debug_dram_crc_srcaddr, arisc_debug_dram_crc_len);

	return size;
}
Exemplo n.º 7
0
static int __init arisc_init(void)
{
	int ret;

	ARISC_LOG("sunxi-arisc driver v%s\n", DRV_VERSION);

	ret = platform_driver_register(&sunxi_arisc_driver);
	if (IS_ERR_VALUE(ret)) {
		ARISC_ERR("register sunxi arisc platform driver failed\n");
		goto err_platform_driver_register;
	}
	ret = platform_device_register(&sunxi_arisc_device);
	if (IS_ERR_VALUE(ret)) {
		ARISC_ERR("register sunxi arisc platform device failed\n");
		goto err_platform_device_register;
	}

	sunxi_arisc_sysfs(&sunxi_arisc_device);

	/* arisc init ok */
	arisc_notify(ARISC_INIT_READY, NULL);

	return 0;

err_platform_device_register:
	platform_device_unregister(&sunxi_arisc_device);
err_platform_driver_register:
	platform_driver_unregister(&sunxi_arisc_driver);
	return -EINVAL;
}
Exemplo n.º 8
0
static ssize_t arisc_freq_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t size)
{
	u32 freq = 0;
	u32 pll  = 0;
	u32 mode = 0;
	u32 ret = 0;

	sscanf(buf, "%u %u", &pll, &freq);

#if (defined CONFIG_ARCH_SUN8IW1P1) || (defined CONFIG_ARCH_SUN8IW3P1) || (defined CONFIG_ARCH_SUN8IW5P1)
	if ((pll != 1) || (freq < 0) || (freq > 3000000)) {
		ARISC_WRN("invalid pll [%u] or freq [%u] to set, this platform only support pll1, freq [0, 3000000]KHz\n", pll, freq);
		ARISC_WRN("pls echo like that: echo pll freq > freq\n");
		return size;
	}
#elif (defined CONFIG_ARCH_SUN9IW1P1) || (defined CONFIG_ARCH_SUN8IW6P1)
	if (((pll != 1) && (pll != 2)) || (freq < 0) || (freq > 3000000)) {
		ARISC_WRN("invalid pll [%u] or freq [%u] to set, this platform only support pll1 and pll2, freq [0, 3000000]KHz\n", pll, freq);
		ARISC_WRN("pls echo like that: echo pll freq > freq\n");
		return size;
	}
#endif

	arisc_pll = pll;
	ret = arisc_dvfs_set_cpufreq(freq, pll, mode, NULL, NULL);
	if (ret) {
		ARISC_ERR("pll%u freq set to %u fail\n", pll, freq);
	} else {
		ARISC_LOG("pll%u freq set to %u success\n", pll, freq);
	}

	return size;
}
Exemplo n.º 9
0
static int arisc_wait_ready(unsigned int timeout)
{
	/* wait arisc startup ready */
	while (1) {
		/*
		 * linux cpu interrupt is disable now,
		 * we should query message by hand.
		 */
		struct arisc_message *pmessage = arisc_hwmsgbox_query_message();
		if (pmessage == NULL) {
			/* try to query again */
			continue;
		}
		/* query valid message */
		if (pmessage->type == ARISC_STARTUP_NOTIFY) {
			/* check arisc software and driver version match or not */
			if (pmessage->paras[0] != ARISC_VERSIONS) {
				ARISC_ERR("arisc firmware:%d and driver version:%u not matched\n", pmessage->paras[0], ARISC_VERSIONS);
				return -EINVAL;
			} else {
				/* printf the main and sub version string */
				memcpy((void *)arisc_version, (const void*)(&(pmessage->paras[1])), 40);
				ARISC_LOG("arisc version: [%s]\n", arisc_version);
			}

			/* received arisc startup ready message */
			ARISC_INF("arisc startup ready\n");
			if ((pmessage->attr & ARISC_MESSAGE_ATTR_SOFTSYN) ||
				(pmessage->attr & ARISC_MESSAGE_ATTR_HARDSYN)) {
				/* synchronous message, just feedback it */
				ARISC_INF("arisc startup notify message feedback\n");
				pmessage->paras[0] = (uint32_t)dts_cfg.image.base;
				arisc_hwmsgbox_feedback_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
			} else {
				/* asyn message, free message directly */
				ARISC_INF("arisc startup notify message free directly\n");
				arisc_message_free(pmessage);
			}
			break;
		}
		/*
		 * invalid message detected, ignore it.
		 * by superm at 2012-7-6 18:34:38.
		 */
		ARISC_WRN("arisc startup waiting ignore message\n");
		if ((pmessage->attr & ARISC_MESSAGE_ATTR_SOFTSYN) ||
			(pmessage->attr & ARISC_MESSAGE_ATTR_HARDSYN)) {
			/* synchronous message, just feedback it */
			arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
		} else {
			/* asyn message, free message directly */
			arisc_message_free(pmessage);
		}
		/* we need waiting continue */
	}

	return 0;
}
Exemplo n.º 10
0
int sunxi_arisc_probe(void *cfg)
{
	struct arisc_para para;

	ARISC_LOG("sunxi-arisc driver begin startup %d\n", arisc_debug_level);
	memcpy((void *)&dts_cfg, (const void *)cfg, sizeof(struct dts_cfg));

	/* init arisc parameter */
	sunxi_arisc_para_init(&para);

	/* load arisc */
	sunxi_load_arisc(dts_cfg.image.base, dts_cfg.image.size,
	                 (void *)(&para), sizeof(struct arisc_para));

	/* initialize hwspinlock */
	ARISC_INF("hwspinlock initialize\n");
	arisc_hwspinlock_init();

	/* initialize hwmsgbox */
	ARISC_INF("hwmsgbox initialize\n");
	arisc_hwmsgbox_init();

	/* initialize message manager */
	ARISC_INF("message manager initialize start:0x%llx, size:0x%llx\n", dts_cfg.space.msgpool_dst, dts_cfg.space.msgpool_size);
	arisc_message_manager_init((void *)dts_cfg.space.msgpool_dst, dts_cfg.space.msgpool_size);

	/* wait arisc ready */
	ARISC_INF("wait arisc ready....\n");
	if (arisc_wait_ready(10000)) {
		ARISC_LOG("arisc startup failed\n");
	}

	arisc_set_paras();

	/* enable arisc asyn tx interrupt */
	//arisc_hwmsgbox_enable_receiver_int(ARISC_HWMSGBOX_ARISC_ASYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327);

	/* enable arisc syn tx interrupt */
	//arisc_hwmsgbox_enable_receiver_int(ARISC_HWMSGBOX_ARISC_SYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327);

	/* arisc initialize succeeded */
	ARISC_LOG("sunxi-arisc driver v%s is starting\n", DRV_VERSION);

	return 0;
}
Exemplo n.º 11
0
static ssize_t arisc_p2wi_read_block_data_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	sscanf(buf, "%x", (u32 *)&regaddr);
	if ((regaddr < 0) || (regaddr > 0xff)) {
		ARISC_WRN("invalid p2wi paras, regaddr:0x%x\n", regaddr);
		ARISC_LOG("pls echo like that: echo regaddr > p2wi_read_block_data\n");
		return size;
	}

	block_cfg.msgattr = ARISC_MESSAGE_ATTR_SOFTSYN;
	block_cfg.len = 1;
	block_cfg.addr = &regaddr;
	block_cfg.data = &data;

	ARISC_LOG("p2wi read regaddr:0x%x\n", *block_cfg.addr);

	return size;
}
Exemplo n.º 12
0
static int sunxi_arisc_resume(struct device *dev)
{
	unsigned long wake_event;
	standby_info_para_t sst_info;

	atomic_set(&arisc_suspend_flag, 0);
	arisc_query_wakeup_source(&wake_event);
	if (wake_event & CPUS_WAKEUP_POWER_EXP) {
		ARISC_LOG("power exception during standby, enable:0x%x" \
				  " expect state:0x%x, expect consumption:%dmw", \
				arisc_powchk_back.power_state.enable, \
				arisc_powchk_back.power_state.power_reg, \
				arisc_powchk_back.power_state.system_power);
		arisc_query_standby_power(&sst_info);
		ARISC_LOG(" real state:0x%x, real consumption:%dmw\n", \
				sst_info.power_state.power_reg, \
				sst_info.power_state.system_power);
	}

	return 0;
}
Exemplo n.º 13
0
static ssize_t arisc_p2wi_read_block_data_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	ssize_t size = 0;
	u32 ret = 0;

	if ((block_cfg.addr == NULL) || (block_cfg.data == NULL) ||
		(*block_cfg.addr < 0) || (*block_cfg.addr > 0xff)) {
		ARISC_LOG("invalid p2wi paras, regaddr:0x%x\n", block_cfg.addr ? *block_cfg.addr : 0);
		ARISC_LOG("pls echo like that: echo regaddr > p2wi_read_block_data\n");
		return size;
	}

	ret = arisc_p2wi_read_block_data(&block_cfg);
	if (ret) {
		ARISC_LOG("p2wi read data:0x%x from regaddr:0x%x fail\n", *block_cfg.data, *block_cfg.addr);
	} else {
		ARISC_LOG("p2wi read data:0x%x from regaddr:0x%x success\n", *block_cfg.data, *block_cfg.addr);
	}
	size = sprintf(buf, "%x\n", data);

	return size;
}
Exemplo n.º 14
0
/*
*********************************************************************************************************
*                                       SEND MESSAGE BY HWMSGBOX
*
* Description: 	send one message to another processor by hwmsgbox.
*
* Arguments  : 	pmessage 	: the pointer of sended message frame.
*				timeout		: the wait time limit when message fifo is full,
*							  it is valid only when parameter mode = HWMSG_SEND_WAIT_TIMEOUT.
*
* Returns    : 	0 if send message succeeded, other if failed.
*********************************************************************************************************
*/
int arisc_hwmsgbox_send_message(struct arisc_message *pmessage, unsigned int timeout)
{
	volatile unsigned long value;
	
	if (pmessage == (struct arisc_message *)(NULL)) {
		return -EINVAL;
	}
	if (pmessage->attr & ARISC_MESSAGE_ATTR_HARDSYN) {
		//use ac327 hwsyn transmit channel.
		while (readl(IO_ADDRESS(AW_MSGBOX_FIFO_STATUS_REG(ARISC_HWMSGBOX_AC327_SYN_TX_CH))) == 1) {
			//message-queue fifo is full, waiting always
			;
		}
		value = ((volatile unsigned long)pmessage) - arisc_sram_a2_vbase; 
		ARISC_INF("ac327 send hard syn message : %x\n", (unsigned int)value);
		writel(value, IO_ADDRESS(AW_MSGBOX_MSG_REG(ARISC_HWMSGBOX_AC327_SYN_TX_CH)));
		
		//hwsyn messsage must feedback use syn rx channel
		while (readl(IO_ADDRESS(AW_MSGBOX_MSG_STATUS_REG(ARISC_HWMSGBOX_AC327_SYN_RX_CH))) == 0) {
			//message not valid
			;
		}
		//check message valid
		if (value != (readl(IO_ADDRESS(AW_MSGBOX_MSG_REG(ARISC_HWMSGBOX_AC327_SYN_RX_CH))))) {
			ARISC_ERR("hard syn message error\n");
			return -EINVAL;
		}
		ARISC_INF("ac327 hard syn message [%x, %x] feedback\n", (unsigned int)value, (unsigned int)pmessage->type);
		return 0;
	}
	
	//use ac327 asyn transmit channel.
	while (readl(IO_ADDRESS(AW_MSGBOX_FIFO_STATUS_REG(ARISC_HWMSGBOX_ARISC_ASYN_RX_CH))) == 1) {
		//message-queue fifo is full, waiting always
		;
	}
	//write message to message-queue fifo.
	value = ((volatile unsigned long)pmessage) - arisc_sram_a2_vbase; 
	ARISC_LOG("ac327 send soft syn or asyn message : %x\n", (unsigned int)value);
	writel(value, IO_ADDRESS(AW_MSGBOX_MSG_REG(ARISC_HWMSGBOX_ARISC_ASYN_RX_CH)));
	
	//syn messsage must wait message feedback
	if (pmessage->attr & ARISC_MESSAGE_ATTR_SOFTSYN) {
		ARISC_ERR("standby arisc driver not support soft syn message transfer\n");
		return -EINVAL;
	}
	
	return 0;
}
Exemplo n.º 15
0
static ssize_t arisc_rsb_read_block_data_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	ssize_t size = 0;
	u32 ret = 0;

	if ((block_cfg.regaddr == NULL) || (block_cfg.data == NULL) ||
		(block_cfg.devaddr > 0xff) ||
		((block_cfg.datatype !=  RSB_DATA_TYPE_BYTE) && (block_cfg.datatype !=  RSB_DATA_TYPE_HWORD) && (block_cfg.datatype !=  RSB_DATA_TYPE_WORD))) {
		ARISC_WRN("invalid rsb paras, devaddr:0x%x, regaddr:0x%x, datatype:0x%x\n", block_cfg.devaddr, block_cfg.regaddr ? *block_cfg.regaddr : 0, block_cfg.datatype);
		ARISC_WRN("pls echo like that: echo devaddr regaddr datatype > rsb_read_block_data\n");
		return size;
	}

	ret = arisc_rsb_read_block_data(&block_cfg);
	if (ret) {
		ARISC_LOG("rsb read data:0x%x from devaddr:0x%x regaddr:0x%x fail\n", *block_cfg.data, block_cfg.devaddr, *block_cfg.regaddr);
	} else {
		ARISC_LOG("rsb read data:0x%x from devaddr:0x%x regaddr:0x%x success\n", *block_cfg.data, block_cfg.devaddr, *block_cfg.regaddr);
	}
	size = sprintf(buf, "%x\n", data);

	return size;
}
Exemplo n.º 16
0
static ssize_t arisc_debug_baudrate_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	u32 value = 0;

	sscanf(buf, "%u", &value);
	if ((value != 115200) && (value != 57600) && (value != 9600)) {
		ARISC_WRN("invalid arisc uart baudrate [%d] to set\n", value);
		return size;
	}

	arisc_debug_baudrate = value;
	arisc_set_uart_baudrate(arisc_debug_baudrate);
	ARISC_LOG("debug_baudrate change to %d\n", arisc_debug_baudrate);

	return size;
}
Exemplo n.º 17
0
static ssize_t arisc_debug_mask_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t size)
{
	u32 value = 0;

	sscanf(buf, "%u", &value);
	if ((value < 0) || (value > 3)) {
		ARISC_WRN("invalid arisc debug mask [%d] to set\n", value);
		return size;
	}

	arisc_debug_level = value;
	arisc_set_debug_level(arisc_debug_level);
	ARISC_LOG("debug_mask change to %d\n", arisc_debug_level);

	return size;
}
Exemplo n.º 18
0
static ssize_t arisc_power_state_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	unsigned long value;

	if (kstrtoul(buf, 0, &value) < 0) {
		ARISC_ERR("illegal value, only one para support");
		return -EINVAL;
	}
	arisc_powchk_back.power_state.power_reg = value;

	arisc_set_standby_power_cfg(&arisc_powchk_back);
	ARISC_LOG("standby_power_set power_state 0x%x\n",
			arisc_powchk_back.power_state.power_reg);

	return size;
}
Exemplo n.º 19
0
static ssize_t arisc_power_consum_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	unsigned long value;

	if (kstrtoul(buf, 0, &value) < 0) {
		if (1 != sscanf(buf, "%lu", &value)) {
			ARISC_ERR("illegal value, only one para support");
			return -EINVAL;
		}
	}
	arisc_powchk_back.power_state.system_power = value;

	arisc_set_standby_power_cfg(&arisc_powchk_back);
	ARISC_LOG("standby_power_set power_consum %dmw\n",
			arisc_powchk_back.power_state.system_power);

	return size;
}
Exemplo n.º 20
0
static ssize_t arisc_rsb_read_block_data_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	sscanf(buf, "%x %x %x", &devaddr, (u32 *)&regaddr, &datatype);
	if ((devaddr > 0xff) ||
	((datatype !=  RSB_DATA_TYPE_BYTE) && (datatype !=  RSB_DATA_TYPE_HWORD) && (datatype !=  RSB_DATA_TYPE_WORD))) {
		ARISC_WRN("invalid rsb paras to set, devaddr:0x%x, regaddr:0x%x, datatype:0x%x\n", devaddr, regaddr, datatype);
		ARISC_WRN("pls echo like that: echo devaddr regaddr datatype > rsb_read_block_data\n");
		return size;
	}

	block_cfg.msgattr = ARISC_MESSAGE_ATTR_SOFTSYN;
	block_cfg.datatype = datatype;
	block_cfg.len = 1;
	block_cfg.devaddr = devaddr;
	block_cfg.regaddr = &regaddr;
	block_cfg.data = &data;

	ARISC_LOG("rsb read data from devaddr:0x%x regaddr:0x%x\n", devaddr, regaddr);

	return size;
}
Exemplo n.º 21
0
static ssize_t arisc_dram_crc_result_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	u32 error = 0;
	u32 total_count = 0;
	u32 error_count = 0;

	sscanf(buf, "%u %u %u", &error, &total_count, &error_count);
	if ((error != 0) && (error != 1)) {
		ARISC_WRN("invalid arisc dram crc result [%d] [%d] [%d] to set\n", error, total_count, error_count);
		return size;
	}

	arisc_debug_dram_crc_error = error;
	arisc_debug_dram_crc_total_count = total_count;
	arisc_debug_dram_crc_error_count = error_count;
	arisc_set_dram_crc_result((unsigned long)arisc_debug_dram_crc_error,
							  (unsigned long)arisc_debug_dram_crc_total_count,
							  (unsigned long)arisc_debug_dram_crc_error_count);
	ARISC_LOG("debug_dram_crc_result change to error:%u total count:%u error count:%u\n",
			arisc_debug_dram_crc_error, arisc_debug_dram_crc_total_count, arisc_debug_dram_crc_error_count);

	return size;
}
Exemplo n.º 22
0
static ssize_t arisc_power_enable_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	unsigned long value;

	if (kstrtoul(buf, 0, &value) < 0) {
		ARISC_ERR("illegal value, only one para support\n");
		return -EINVAL;
	}

	if (value & ~(CPUS_ENABLE_POWER_EXP | CPUS_WAKEUP_POWER_STA | CPUS_WAKEUP_POWER_CSM)) {
		ARISC_ERR("invalid format, 'enable' should:\n"\
				  "  bit31:enable power check during standby\n"\
				  "  bit1: enable wakeup when power state exception\n"\
				  "  bit0: enable wakeup when power consume exception\n");
		return size;
	}

	arisc_powchk_back.power_state.enable = value;
	arisc_set_standby_power_cfg(&arisc_powchk_back);
	ARISC_LOG("standby_power_set enable:0x%x\n", arisc_powchk_back.power_state.enable);

	return size;
}
Exemplo n.º 23
0
static void __exit arisc_exit(void)
{
	platform_device_unregister(&sunxi_arisc_device);
	platform_driver_unregister(&sunxi_arisc_driver);
	ARISC_LOG("module unloaded\n");
}
Exemplo n.º 24
0
static int arisc_wait_ready(unsigned int timeout)
{
	unsigned long          expire;
#ifdef CONFIG_SUNXI_MODULE
	struct sunxi_module_info arisc_module_info;
#endif

	expire = msecs_to_jiffies(timeout) + jiffies;

	/* wait arisc startup ready */
	while (1) {
		/*
		 * linux cpu interrupt is disable now,
		 * we should query message by hand.
		 */
		struct arisc_message *pmessage = arisc_hwmsgbox_query_message();
		if (pmessage == NULL) {
			if (time_is_before_eq_jiffies(expire)) {
				return -ETIMEDOUT;
			}
			/* try to query again */
			continue;
		}
		/* query valid message */
		if (pmessage->type == ARISC_STARTUP_NOTIFY) {
			/* check arisc software and driver version match or not */
			if (pmessage->paras[0] != ARISC_VERSIONS) {
				ARISC_ERR("arisc firmware:%d and driver version:%d not matched\n", pmessage->paras[0], ARISC_VERSIONS);
				return -EINVAL;
			} else {
				/* printf the main and sub version string */
				memcpy((void *)arisc_version, (const void*)(&(pmessage->paras[1])), 40);
				ARISC_LOG("arisc version: [%s]\n", arisc_version);
#ifdef CONFIG_SUNXI_MODULE
				strncpy((char *)arisc_module_info.module, (const char *)"arisc", 16);
				strncpy((char *)arisc_module_info.version, (const char *)arisc_version, 16);
				sunxi_module_info_register(&arisc_module_info);
#endif
			}

			/* received arisc startup ready message */
			ARISC_INF("arisc startup ready\n");
			if ((pmessage->attr & ARISC_MESSAGE_ATTR_SOFTSYN) ||
				(pmessage->attr & ARISC_MESSAGE_ATTR_HARDSYN)) {
				/* synchronous message, just feedback it */
				ARISC_INF("arisc startup notify message feedback\n");
				pmessage->paras[0] = virt_to_phys((void *)&arisc_binary_start);
				arisc_hwmsgbox_feedback_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
			} else {
				/* asyn message, free message directly */
				ARISC_INF("arisc startup notify message free directly\n");
				arisc_message_free(pmessage);
			}
			break;
		}
		/*
		 * invalid message detected, ignore it.
		 * by sunny at 2012-7-6 18:34:38.
		 */
		ARISC_WRN("arisc startup waiting ignore message\n");
		if ((pmessage->attr & ARISC_MESSAGE_ATTR_SOFTSYN) ||
			(pmessage->attr & ARISC_MESSAGE_ATTR_HARDSYN)) {
			/* synchronous message, just feedback it */
			arisc_hwmsgbox_send_message(pmessage, ARISC_SEND_MSG_TIMEOUT);
		} else {
			/* asyn message, free message directly */
			arisc_message_free(pmessage);
		}
		/* we need waiting continue */
	}

	return 0;
}
Exemplo n.º 25
0
static int  sunxi_arisc_probe(struct platform_device *pdev)
{
	int binary_len;
	int ret;

	ARISC_INF("arisc initialize\n");

	/* cfg sunxi arisc clk */
	ret = sunxi_arisc_clk_cfg(pdev);
	if (ret) {
		ARISC_ERR("sunxi-arisc clk cfg failed\n");
		return -EINVAL;
	}

	/* cfg sunxi arisc pin */
	ret = sunxi_arisc_pin_cfg(pdev);
	if (ret) {
		ARISC_ERR("sunxi-arisc pin cfg failed\n");
		return -EINVAL;
	}

	ARISC_INF("sram_a2 vaddr(%x)\n", (unsigned int)arisc_sram_a2_vbase);

#if (defined CONFIG_ARCH_SUN8IW1P1) || (defined CONFIG_ARCH_SUN8IW3P1) || (defined CONFIG_ARCH_SUN8IW5P1) || (defined CONFIG_ARCH_SUN8IW6P1)
	binary_len = 0x13000;
#elif defined CONFIG_ARCH_SUN9IW1P1
	binary_len = (int)(&arisc_binary_end) - (int)(&arisc_binary_start);
#endif
	/* clear sram_a2 area */
	memset((void *)arisc_sram_a2_vbase, 0, SUNXI_SRAM_A2_SIZE);
	/* load arisc system binary data to sram_a2 */
	memcpy((void *)arisc_sram_a2_vbase, (void *)(&arisc_binary_start), binary_len);
	ARISC_INF("move arisc binary data [addr = %x, len = %x] to sram_a2 finished\n",
			 (unsigned int)(&arisc_binary_start), (unsigned int)binary_len);

	/* initialize hwspinlock */
	ARISC_INF("hwspinlock initialize\n");
	arisc_hwspinlock_init();

	/* initialize hwmsgbox */
	ARISC_INF("hwmsgbox initialize\n");
	arisc_hwmsgbox_init();

	/* initialize message manager */
	ARISC_INF("message manager initialize\n");
	arisc_message_manager_init();

	/* set arisc cpu reset to de-assert state */
	ARISC_INF("set arisc reset to de-assert state\n");
#if (defined CONFIG_ARCH_SUN8IW1P1) || (defined CONFIG_ARCH_SUN8IW3P1) || (defined CONFIG_ARCH_SUN8IW5P1) || (defined CONFIG_ARCH_SUN8IW6P1)
	{
		volatile unsigned long value;
		value = readl((IO_ADDRESS(SUNXI_R_CPUCFG_PBASE) + 0x0));
		value &= ~1;
		writel(value, (IO_ADDRESS(SUNXI_R_CPUCFG_PBASE) + 0x0));
		value = readl((IO_ADDRESS(SUNXI_R_CPUCFG_PBASE) + 0x0));
		value |= 1;
		writel(value, (IO_ADDRESS(SUNXI_R_CPUCFG_PBASE) + 0x0));
	}
#elif defined CONFIG_ARCH_SUN9IW1P1
	{
		volatile unsigned long value;
		value = readl((IO_ADDRESS(SUNXI_R_PRCM_PBASE) + 0x0));
		value &= ~1;
		writel(value, (IO_ADDRESS(SUNXI_R_PRCM_PBASE) + 0x0));
		value = readl((IO_ADDRESS(SUNXI_R_PRCM_PBASE) + 0x0));
		value |= 1;
		writel(value, (IO_ADDRESS(SUNXI_R_PRCM_PBASE) + 0x0));
	}
#endif

	/* wait arisc ready */
	ARISC_INF("wait arisc ready....\n");
	if (arisc_wait_ready(10000)) {
		ARISC_LOG("arisc startup failed\n");
	}

	/* enable arisc asyn tx interrupt */
	arisc_hwmsgbox_enable_receiver_int(ARISC_HWMSGBOX_ARISC_ASYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327);

	/* enable arisc syn tx interrupt */
	arisc_hwmsgbox_enable_receiver_int(ARISC_HWMSGBOX_ARISC_SYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327);

	/* config dvfs v-f table */
	if (arisc_dvfs_cfg_vf_table()) {
		ARISC_WRN("config dvfs v-f table failed\n");
	}

#if (defined CONFIG_ARCH_SUN8IW1P1) || (defined CONFIG_ARCH_SUN8IW6P1) || (defined CONFIG_ARCH_SUN9IW1P1)
	/* config ir config paras */
	if (arisc_config_ir_paras()) {
		ARISC_WRN("config ir paras failed\n");
	}
#endif

#if (defined CONFIG_ARCH_SUN8IW1P1) || (defined CONFIG_ARCH_SUN8IW3P1) || (defined CONFIG_ARCH_SUN8IW5P1)
	/* config pmu config paras */
	if (arisc_config_pmu_paras()) {
		ARISC_WRN("config pmu paras failed\n");
	}
#endif

	/* config dram config paras */
	if (arisc_config_dram_paras()) {
		ARISC_WRN("config dram paras failed\n");
	}
#if (defined CONFIG_ARCH_SUN8IW5P1) || (defined CONFIG_ARCH_SUN9IW1P1)
	/* config standby power paras */
	if (arisc_sysconfig_sstpower_paras()) {
		ARISC_WRN("config sst power paras failed\n");
	}
#endif
	atomic_set(&arisc_suspend_flag, 0);

	/*
	 * detect sunxi chip id
	 * include soc chip id, pmu chip id and serial.
	 */
	sunxi_chip_id_init();

	/* arisc initialize succeeded */
	ARISC_LOG("sunxi-arisc driver v%s startup succeeded\n", DRV_VERSION);


	return 0;
}