static int __init ar100_init(void) { int ret; AR100_LOG("sun6i ar100 driver v%s\n", DRV_VERSION); ret = platform_driver_register(&sun6i_ar100_driver); if (IS_ERR_VALUE(ret)) { AR100_ERR("register sun6i ar100 platform driver failed\n"); goto err_platform_driver_register; } ret = platform_device_register(&sun6i_ar100_device); if (IS_ERR_VALUE(ret)) { AR100_ERR("register sun6i ar100 platform device failed\n"); goto err_platform_device_register; } sun6i_ar100_sysfs(&sun6i_ar100_device); return 0; err_platform_device_register: platform_device_unregister(&sun6i_ar100_device); err_platform_driver_register: platform_driver_unregister(&sun6i_ar100_driver); return -EINVAL; }
static ssize_t ar100_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)) || ((dram_crc_srcaddr < 0x40000000) || (dram_crc_srcaddr > 0xc0000000)) || ((dram_crc_len < 0) || (dram_crc_len > (0x80000000)))) { AR100_WRN("invalid ar100 debug dram crc paras [%x] [%x] [%x] to set\n", dram_crc_en, dram_crc_srcaddr, dram_crc_len); return size; } ar100_debug_dram_crc_en = dram_crc_en; ar100_debug_dram_crc_srcaddr = dram_crc_srcaddr; ar100_debug_dram_crc_len = dram_crc_len; ar100_set_dram_crc_paras(ar100_debug_dram_crc_en, ar100_debug_dram_crc_srcaddr, ar100_debug_dram_crc_len); AR100_LOG("dram_crc_en=0x%x, dram_crc_srcaddr=0x%x, dram_crc_len=0x%x\n", ar100_debug_dram_crc_en, ar100_debug_dram_crc_srcaddr, ar100_debug_dram_crc_len); return size; }
/* ********************************************************************************************************* * 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 ar100_hwmsgbox_send_message(struct ar100_message *pmessage, unsigned int timeout) { volatile unsigned long value; if (pmessage == NULL) { return -EINVAL; } if (pmessage->attr & AR100_MESSAGE_ATTR_HARDSYN) { //use ac327 hwsyn transmit channel. while (readl(IO_ADDRESS(AW_MSGBOX_FIFO_STATUS_REG(AR100_HWMSGBOX_AC327_SYN_TX_CH))) == 1) { //message-queue fifo is full, waiting always ; } value = ((volatile unsigned long)pmessage) - ar100_sram_a2_vbase; AR100_INF("ac327 send hard syn message : %x\n", (unsigned int)value); writel(value, IO_ADDRESS(AW_MSGBOX_MSG_REG(AR100_HWMSGBOX_AC327_SYN_TX_CH))); //hwsyn messsage must feedback use syn rx channel while (readl(IO_ADDRESS(AW_MSGBOX_MSG_STATUS_REG(AR100_HWMSGBOX_AC327_SYN_RX_CH))) == 0) { //message not valid ; } //check message valid if (value != (readl(IO_ADDRESS(AW_MSGBOX_MSG_REG(AR100_HWMSGBOX_AC327_SYN_RX_CH))))) { AR100_ERR("hard syn message error\n"); return -EINVAL; } AR100_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(AR100_HWMSGBOX_AR100_ASYN_RX_CH))) == 1) { //message-queue fifo is full, waiting always ; } //write message to message-queue fifo. value = ((volatile unsigned long)pmessage) - ar100_sram_a2_vbase; AR100_LOG("ac327 send message : %x\n", (unsigned int)value); writel(value, IO_ADDRESS(AW_MSGBOX_MSG_REG(AR100_HWMSGBOX_AR100_ASYN_RX_CH))); //syn messsage must wait message feedback if (pmessage->attr & AR100_MESSAGE_ATTR_SOFTSYN) { AR100_ERR("standby ar100 driver not support soft syn message transfer\n"); return -EINVAL; } return 0; }
static ssize_t ar100_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 != 57600) && (value != 9600)) { AR100_WRN("invalid ar100 uart baudrate [%d] to set\n", value); return size; } ar100_debug_baudrate = value; ar100_set_uart_baudrate(ar100_debug_baudrate); AR100_LOG("debug_baudrate change to %d\n", ar100_debug_baudrate); return size; }
static ssize_t ar100_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)) { AR100_WRN("invalid ar100 debug mask [%d] to set\n", value); return size; } ar100_debug_level = value; ar100_set_debug_level(ar100_debug_level); AR100_LOG("debug_mask change to %d\n", ar100_debug_level); return size; }
static ssize_t ar100_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)) || (total_count < 0) || (error_count < 0)) { AR100_WRN("invalid ar100 dram crc result [%d] [%d] [%d] to set\n", error, total_count, error_count); return size; } ar100_debug_dram_crc_error = error; ar100_debug_dram_crc_total_count = total_count; ar100_debug_dram_crc_error_count = error_count; ar100_set_dram_crc_result((unsigned long)ar100_debug_dram_crc_error, (unsigned long)ar100_debug_dram_crc_total_count, (unsigned long)ar100_debug_dram_crc_error_count); AR100_LOG("debug_dram_crc_result change to error:%u total count:%u error count:%u\n", ar100_debug_dram_crc_error, ar100_debug_dram_crc_total_count, ar100_debug_dram_crc_error_count); return size; }
static void __exit ar100_exit(void) { platform_device_unregister(&sun6i_ar100_device); platform_driver_unregister(&sun6i_ar100_driver); AR100_LOG("module unloaded\n"); }
static int sun6i_ar100_probe(struct platform_device *pdev) { int binary_len; script_item_u script_val; script_item_value_type_e type; AR100_INF("ar100 initialize\n"); /* * request ar100 resources: * p2wi/uart gpio... */ sw_gpio_setcfg(GPIOL(0), 3); /* p2wi sck */ sw_gpio_setcfg(GPIOL(1), 3); /* p2wi sda */ type = script_get_item("cpus_config_paras", "cpus_uart_debug_used", &script_val); if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { AR100_WRN("ar100 uart debug config type err!"); script_val.val = 1; } if (script_val.val) { sw_gpio_setcfg(GPIOL(2), 2); /* uart tx */ sw_gpio_setcfg(GPIOL(3), 2); /* uart rx */ } AR100_INF("ar100 uart debug config [%s] [%s] : %d\n", "cpus_config_paras", "cpus_uart_debug_used", script_val.val); AR100_INF("sram_a2 vaddr(%x)\n", (unsigned int)ar100_sram_a2_vbase); /* clear sram_a2 area */ memset((void *)ar100_sram_a2_vbase, 0, AW_SRAM_A2_SIZE); /* load ar100 system binary data to sram_a2 */ binary_len = 0x13000; memcpy((void *)ar100_sram_a2_vbase, (void *)(&ar100_binary_start), binary_len); printk("move ar100 binary data [addr = %x, len = %x] to sram_a2 finished\n", (unsigned int)(&ar100_binary_start), (unsigned int)binary_len); /* initialize hwspinlock */ AR100_INF("hwspinlock initialize\n"); ar100_hwspinlock_init(); /* initialize hwmsgbox */ AR100_INF("hwmsgbox initialize\n"); ar100_hwmsgbox_init(); /* initialize message manager */ AR100_INF("message manager initialize\n"); ar100_message_manager_init(); /* set ar100 cpu reset to de-assert state */ AR100_INF("set ar100 reset to de-assert state\n"); { volatile unsigned long value; value = readl((IO_ADDRESS(AW_R_CPUCFG_BASE) + 0x0)); value |= 1; writel(value, (IO_ADDRESS(AW_R_CPUCFG_BASE) + 0x0)); } /* wait ar100 ready */ AR100_INF("wait ar100 ready....\n"); if (ar100_wait_ready(10000)) { AR100_LOG("ar100 startup failed\n"); } /* enable ar100 asyn tx interrupt */ ar100_hwmsgbox_enable_receiver_int(AR100_HWMSGBOX_AR100_ASYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327); /* enable ar100 syn tx interrupt */ ar100_hwmsgbox_enable_receiver_int(AR100_HWMSGBOX_AR100_SYN_TX_CH, AW_HWMSG_QUEUE_USER_AC327); /* config dvfs v-f table */ if (ar100_dvfs_cfg_vf_table()) { AR100_WRN("config dvfs v-f table failed\n"); } /* config dram config paras */ if (ar100_config_dram_paras()) { AR100_WRN("config dram paras failed\n"); } /* config ir config paras */ if (ar100_config_ir_paras()) { AR100_WRN("config ir paras failed\n"); } /* config pmu config paras */ if (ar100_config_pmu_paras()) { AR100_WRN("config pmu paras failed\n"); } #ifdef CONFIG_PM atomic_set(&ar100_suspend_flag, 0); #endif /* ar100 initialize succeeded */ AR100_INF("ar100 startup succeeded, driver version : %d\n", AR100_VERSIONS); return 0; }