int hsi_reconfigure_protocol(void) { int ret = 0; /* ACWAKE ->LOW */ ret = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_ACWAKE_DOWN, NULL); if (ret == 0) printk(KERN_INFO "ACWAKE pulled low in %s()\n", __func__); else printk(KERN_INFO "ACWAKE down fail!! %d\n", ret); /*Clse channel 0 */ ret = if_hsi_closechannel(&hsi_protocol_iface.channels[0]); if (ret < 0) { pr_err("Can not Close channel 0. Can not Stop HSI protocol for flashless\n"); goto err; } printk(KERN_INFO "(%s)(%d) hsi_start_protocol Start.\n", __func__, __LINE__); hsi_start_protocol(); printk(KERN_INFO "(%s)(%d) hsi_start_protocol Done.\n", __func__, __LINE__); err: return ret; }
static int if_hsi_set_wakeline(struct if_hsi_channel *channel, unsigned int state) { int ret; spin_lock_bh(&channel->acwake_lock); if (channel->acwake == state) { spin_unlock_bh(&channel->acwake_lock); return 0; } ret = hsi_ioctl(channel->dev, state ? HSI_IOCTL_ACWAKE_UP : HSI_IOCTL_ACWAKE_DOWN, NULL); if (ret) { if (ret != -EPERM) pr_err("[MIPI-HSI] ACWAKE(%d) setting fail : %d\n", state, ret); /* duplicate operation */ if (ret == -EPERM) channel->acwake = state; spin_unlock_bh(&channel->acwake_lock); return ret; } channel->acwake = state; spin_unlock_bh(&channel->acwake_lock); pr_debug("[MIPI-HSI] ACWAKE_%d(%d)\n", channel->channel_id, state); return 0; }
void if_hsi_set_wakeline(int ch, unsigned int state) { struct if_hsi_channel *channel; channel = &hsi_protocol_iface.channels[ch]; hsi_ioctl(channel->dev, state ? HSI_IOCTL_ACWAKE_UP : HSI_IOCTL_ACWAKE_DOWN, NULL); }
//========================================================// // ++ Flashless Boot. ++ // //========================================================// int hsi_start_protocol_single(void) { int ret = 0; struct hst_ctx tx_config; struct hsr_ctx rx_config; /*Open channel 0 */ ret = if_hsi_openchannel(&hsi_protocol_iface.channels[0]); if (ret < 0) { pr_err("Can not Open channel 0. Can not start HSI protocol\n"); goto err; } else printk(KERN_INFO "if_hsi_openchannel() returned %d\n", ret); /*Set Tx Config*/ hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_GET_TX, &tx_config); tx_config.mode = 2; tx_config.channels = 1; tx_config.divisor = 0; ret = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_SET_TX, &tx_config); if (ret < 0) { printk(KERN_INFO "write_hsi_direct : SET_TX Fail : %d\n", ret); return ret; } hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_GET_RX, &rx_config); rx_config.mode = 2; rx_config.channels = 1; rx_config.divisor = 0; //rx_config.timeout = HZ / 2; ret = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_SET_RX, &rx_config); if (ret < 0) { printk(KERN_INFO "write_hsi_direct : SET_RX Fail : %d\n", ret); return ret; } /* ACWAKE ->HIGH */ ret = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_ACWAKE_UP, NULL); if (ret == 0) printk(KERN_INFO "ACWAKE pulled high in %s()\n", __func__); err: return ret; }
int read_hsi_direct(u32 *data, int length) { int retval = 0; #if 0 struct hsr_ctx rx_config; printk(KERN_INFO "read_hsi_direct : len : %d\n", length); hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_GET_RX, &rx_config); rx_config.mode = 2; rx_config.channels = 1; rx_config.divisor = 47; retval = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_SET_RX, &rx_config); if (retval < 0) { printk(KERN_INFO "read_hsi_direct : SET_RX Fail : %d\n", retval); return retval; } printk(KERN_INFO "read_hsi_direct : SET_RX Successful\n"); retval = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_ACWAKE_UP, NULL); if (retval < 0) { printk(KERN_INFO "read_hsi_direct : ACWAKE High Fail : %d\n", retval); return retval; } printk(KERN_INFO "read_hsi_direct : ACWAKE High\n"); #endif #if 0 if ((length > 16) && (length % 4)) length += (4 - (length % 4)); else if (length < 16) length = 16; #endif //printk(KERN_INFO "read_hsi_direct : new len : %d\n", length); retval = hsi_proto_read(0, data, length); if (retval < 0) { printk(KERN_INFO "read_hsi_direct : hsi_proto_read Fail : %d\n", retval); return retval; } //printk(KERN_INFO "read_hsi_direct : Read returned %d\n", retval); return retval; }
static void hsi_conn_err_recovery(struct mipi_link_device *mipi_ld) { int i; int ret; struct hst_ctx tx_config; struct hsr_ctx rx_config; if (mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].opened) { hsi_ioctl(mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev, HSI_IOCTL_SW_RESET, NULL); for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) mipi_ld->hsi_channles[i].opened = 0; } for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) { if (!mipi_ld->hsi_channles[i].opened) if_hsi_open_channel(&mipi_ld->hsi_channles[i]); hsi_ioctl(mipi_ld->hsi_channles[i].dev, HSI_IOCTL_GET_TX, &tx_config); tx_config.mode = 2; tx_config.divisor = 0; /* Speed : 96MHz */ tx_config.channels = HSI_MAX_CHANNELS; hsi_ioctl(mipi_ld->hsi_channles[i].dev, HSI_IOCTL_SET_TX, &tx_config); hsi_ioctl(mipi_ld->hsi_channles[i].dev, HSI_IOCTL_GET_RX, &rx_config); rx_config.mode = 2; rx_config.divisor = 0; /* Speed : 96MHz */ rx_config.channels = HSI_MAX_CHANNELS; hsi_ioctl(mipi_ld->hsi_channles[i].dev, HSI_IOCTL_SET_RX, &rx_config); pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n"); } hsi_ioctl(mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev, HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE, NULL); pr_debug("[MIPI-HSI] Set 4 WIRE MODE\n"); ret = hsi_read(mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev, mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].rx_data, 1); if (ret) pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret); for (i = 1; i < HSI_NUM_OF_USE_CHANNELS; i++) { if ((mipi_ld->hsi_channles[i].recv_step == STEP_RX) && (mipi_ld->hsi_channles[i].rx_count)) { pr_err("[MIPI-HSI] there was rx pending. ch:%d, len:%d", i, mipi_ld->hsi_channles[i].rx_count); ret = hsi_read(mipi_ld->hsi_channles[i].dev, mipi_ld->hsi_channles[i].rx_data, mipi_ld->hsi_channles[i].rx_count / 4); if (ret) pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret); } } pr_debug("[MIPI-HSI] hsi_conn_err_recovery Done\n"); }
int hsi_start_protocol(void) { struct hst_ctx tx_config; struct hsr_ctx rx_config; int i, ret = 0; printk(KERN_INFO "In function %s()\n", __func__); /*Open All channels */ for (i = 0; i <= 5; i++) { ret = if_hsi_openchannel(&hsi_protocol_iface.channels[i]); if (ret < 0) pr_err("Can not Open channel->%d . Can not start HSI protocol\n", i); else printk(KERN_INFO "Channel->%d Open Successful\n", i); /*Set Rx Config*/ hsi_ioctl(hsi_protocol_iface.channels[i].dev, HSI_IOCTL_GET_RX, &rx_config); rx_config.mode = 2; rx_config.divisor = 1; rx_config.channels = HSI_MAX_CHANNELS; ret = hsi_ioctl(hsi_protocol_iface.channels[i].dev, HSI_IOCTL_SET_RX, &rx_config); if (ret == 0) printk(KERN_INFO "SET_RX Successful for ch->%d\n", i); /*Set Tx Config*/ hsi_ioctl(hsi_protocol_iface.channels[i].dev, HSI_IOCTL_GET_TX, &tx_config); tx_config.mode = 2; tx_config.divisor = 1; tx_config.channels = HSI_MAX_CHANNELS; ret = hsi_ioctl(hsi_protocol_iface.channels[i].dev, HSI_IOCTL_SET_TX, &tx_config); if (ret == 0) printk(KERN_INFO "SET_TX Successful for ch->%d\n", i); } /*Make channel-0 tx_state to IDLE*/ hsi_protocol_iface.channels[0].tx_state = HSI_LL_TX_STATE_IDLE; return ret; }
static int hsi_init_handshake(struct mipi_link_device *mipi_ld, int mode) { int ret; int i; struct hst_ctx tx_config; struct hsr_ctx rx_config; switch (mode) { case HSI_INIT_MODE_NORMAL: if (timer_pending(&mipi_ld->hsi_acwake_down_timer)) del_timer(&mipi_ld->hsi_acwake_down_timer); for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) { if (mipi_ld->hsi_channles[i].opened) { hsi_write_cancel(mipi_ld->hsi_channles[i].dev); hsi_read_cancel(mipi_ld->hsi_channles[i].dev); } else { ret = if_hsi_open_channel( &mipi_ld->hsi_channles[i]); if (ret) return ret; } mipi_ld->hsi_channles[i].send_step = STEP_IDLE; mipi_ld->hsi_channles[i].recv_step = STEP_IDLE; hsi_ioctl(mipi_ld->hsi_channles[i].dev, HSI_IOCTL_GET_TX, &tx_config); tx_config.mode = 2; tx_config.divisor = 0; /* Speed : 96MHz */ tx_config.channels = HSI_MAX_CHANNELS; hsi_ioctl(mipi_ld->hsi_channles[i].dev, HSI_IOCTL_SET_TX, &tx_config); hsi_ioctl(mipi_ld->hsi_channles[i].dev, HSI_IOCTL_GET_RX, &rx_config); rx_config.mode = 2; rx_config.divisor = 0; /* Speed : 96MHz */ rx_config.channels = HSI_MAX_CHANNELS; hsi_ioctl(mipi_ld->hsi_channles[i].dev, HSI_IOCTL_SET_RX, &rx_config); pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n"); } hsi_ioctl(mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev, HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE, NULL); pr_debug("[MIPI-HSI] Set 4 WIRE MODE\n"); if (mipi_ld->ld.com_state != COM_ONLINE) mipi_ld->ld.com_state = COM_HANDSHAKE; ret = hsi_read(mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev, mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].rx_data, 1); if (ret) pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret); if (mipi_ld->ld.com_state != COM_ONLINE) schedule_delayed_work(&mipi_ld->start_work, 3 * HZ); pr_debug("[MIPI-HSI] hsi_init_handshake Done : MODE_NORMAL\n"); return 0; case HSI_INIT_MODE_FLASHLESS_BOOT: mipi_ld->ld.com_state = COM_BOOT; if (mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened) { hsi_ioctl(mipi_ld->hsi_channles[ HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SW_RESET, NULL); for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) mipi_ld->hsi_channles[i].opened = 0; } if (!mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened) if_hsi_open_channel( &mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL]); mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].send_step = STEP_IDLE; mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].recv_step = STEP_IDLE; hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_GET_TX, &tx_config); tx_config.mode = 2; tx_config.divisor = 3; /* Speed : 24MHz */ tx_config.channels = 1; hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SET_TX, &tx_config); hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_GET_RX, &rx_config); rx_config.mode = 2; rx_config.divisor = 3; /* Speed : 24MHz */ rx_config.channels = 1; hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SET_RX, &rx_config); pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n"); hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SET_WAKE_RX_3WIRES_MODE, NULL); pr_debug("[MIPI-HSI] Set 3 WIRE MODE\n"); if (!wake_lock_active(&mipi_ld->wlock)) { wake_lock(&mipi_ld->wlock); pr_debug("[MIPI-HSI] wake_lock\n"); } ret = hsi_read(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].rx_data, 1); if (ret) pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret); pr_debug("[MIPI-HSI] hsi_init_handshake Done : FLASHLESS_BOOT\n"); return 0; case HSI_INIT_MODE_FLASHLESS_BOOT_EBL: mipi_ld->ld.com_state = COM_BOOT_EBL; if (mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened) { hsi_ioctl(mipi_ld->hsi_channles[ HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SW_RESET, NULL); for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) mipi_ld->hsi_channles[i].opened = 0; } if (!mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened) if_hsi_open_channel( &mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL]); hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_GET_TX, &tx_config); tx_config.mode = 2; tx_config.divisor = 0; /* Speed : 96MHz */ tx_config.channels = 1; hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SET_TX, &tx_config); hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_GET_RX, &rx_config); rx_config.mode = 2; rx_config.divisor = 0; /* Speed : 96MHz */ rx_config.channels = 1; hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SET_RX, &rx_config); pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n"); hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE, NULL); pr_debug("[MIPI-HSI] Set 4 WIRE MODE\n"); if (!wake_lock_active(&mipi_ld->wlock)) { wake_lock(&mipi_ld->wlock); pr_debug("[MIPI-HSI] wake_lock\n"); } if_hsi_set_wakeline( &mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL], 1); ret = hsi_read(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev, mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].rx_data, 1); if (ret) pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret); pr_debug("[MIPI-HSI] hsi_init_handshake Done : FLASHLESS_BOOT_EBL\n"); return 0; case HSI_INIT_MODE_CP_RAMDUMP: mipi_ld->ld.com_state = COM_CRASH; if (mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].opened) { hsi_ioctl(mipi_ld->hsi_channles[ HSI_CP_RAMDUMP_CHANNEL].dev, HSI_IOCTL_SW_RESET, NULL); for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) mipi_ld->hsi_channles[i].opened = 0; } if (!mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].opened) if_hsi_open_channel( &mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL]); mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].send_step = STEP_IDLE; mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].recv_step = STEP_IDLE; hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev, HSI_IOCTL_GET_TX, &tx_config); tx_config.mode = 2; tx_config.divisor = 0; /* Speed : 96MHz */ tx_config.channels = 1; hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev, HSI_IOCTL_SET_TX, &tx_config); hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev, HSI_IOCTL_GET_RX, &rx_config); rx_config.mode = 2; rx_config.divisor = 0; /* Speed : 96MHz */ rx_config.channels = 1; hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev, HSI_IOCTL_SET_RX, &rx_config); pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n"); hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev, HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE, NULL); pr_debug("[MIPI-HSI] Set 4 WIRE MODE\n"); if (!wake_lock_active(&mipi_ld->wlock)) { wake_lock(&mipi_ld->wlock); pr_debug("[MIPI-HSI] wake_lock\n"); } if_hsi_set_wakeline( &mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL], 1); ret = hsi_read( mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev, mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].rx_data, DUMP_ERR_INFO_SIZE); if (ret) pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret); pr_debug("[MIPI-HSI] hsi_init_handshake Done : RAMDUMP\n"); return 0; default: return -EINVAL; } }
/*Write data to channel*/ int write_hsi(u32 ch, u32 *data, int length) { int ret; //u32 cmd[4] = {0x00000000, 0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC}; struct if_hsi_channel *channel; struct task_struct *read_thread; channel = &hsi_protocol_iface.channels[ch]; channel->tx_buf = data; channel->tx_count = 0; //cmd[0] = protocol_create_cmd(HSI_LL_MSG_OPEN_CONN_OCTET, ch, (void *)&length); //printk(KERN_INFO "data ptr is %x\n", data); if (initialization == 0) { #if 0 /* ACWAKE ->HIGH */ ret = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_ACWAKE_UP, NULL); if (ret == 0) printk(KERN_INFO "ACWAKE pulled high in %s()\n", __func__); else printk(KERN_INFO "ACWAKE pulled high in %s() ERROR : %d\n", __func__, ret); #endif /*Creating read thread*/ read_thread = kthread_run(hsi_read_thrd, NULL, "hsi_read_thread"); initialization++; } /*Wait till previous data transfer is over*/ while (channel->tx_state != HSI_LL_TX_STATE_IDLE) { //printk(KERN_INFO "Wait 5ms previous data transfer isn't over %s()\n", __func__); //msleep(5); return -EAGAIN; } #if 1 /* ACWAKE ->HIGH */ ret = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_ACWAKE_UP, NULL); if (ret == 0) printk(KERN_INFO "ACWAKE pulled high in %s()\n", __func__); else printk(KERN_INFO "ACWAKE pulled high in %s() ERROR : %d\n", __func__, ret); #endif channel->tx_state = HSI_LL_TX_STATE_WAIT_FOR_ACK; //send_cmd(cmd, channel, data) //ret = hsi_proto_write(0, &cmd, 4*4); //printk(KERN_INFO "Write returned %d\n", ret); hsi_protocol_send_command(HSI_LL_MSG_OPEN_CONN_OCTET, ch, length); wait_event_interruptible(ipc_write_wait, channel->tx_count != 0); return channel->tx_count; }