Example #1
0
int pm_reg_write(uint32_t value, mic_ctx_t *mic_ctx, uint32_t regoffset) {
	int err = 0;
if (mic_ctx->bi_family == FAMILY_ABR)
	DBOX_WRITE(value, mic_ctx->mmio.va, regoffset);
else if (mic_ctx->bi_family == FAMILY_KNC)
	SBOX_WRITE(value, mic_ctx->mmio.va, regoffset);

	return err;
}
Example #2
0
int
send_flash_cmd(mic_ctx_t *mic_ctx, MIC_FLASH_CMD_TYPE type, void *data, uint32_t len)
{
	int32_t status = 0;
	uint8_t *mmio_va = mic_ctx->mmio.va;
	sbox_scratch1_reg_t scratch1reg = {0};
	sbox_scratch2_reg_t scratch2reg = {0};
	uint32_t ret = 0;
	void *src;
	struct timeval t;
	struct flash_stat *statbuf = NULL;
	uint64_t temp;
	uint32_t i = 0;
	struct version_struct *verbuf = NULL;
	int32_t offset = 0;
	uint8_t cmddata = 0;

	scratch1reg.bits.status = FLASH_CMD_INVALID;
	switch (type) {
	case FLASH_CMD_READ:

		/*
		 * image address = the upper 20 bits of the 32-bit of scracth2 register
		 * is card side physical address where the flash image resides
		 * program scratch2 register to notify the image address
		 */
		scratch2reg.bits.image_addr = RASMM_DEFAULT_OFFSET >> 12;
		SBOX_WRITE(scratch2reg.value, mmio_va, SBOX_SCRATCH2);

		/* set command */
		scratch1reg.bits.command = FLASH_CMD_READ;
		SBOX_WRITE(scratch1reg.value, mmio_va, SBOX_SCRATCH1);

		mic_send_bootstrap_intr(mic_ctx);
		break;

	case FLASH_CMD_READ_DATA:

		/*
		 * flash read_data command : set pci aperture to 128MB
		 * read the value of scratch2 in a variable
		 */
		ret = SBOX_READ(mmio_va, SBOX_SCRATCH2);
		scratch2reg.value = ret;

		/*
		 * convert physical to virtual address
		 * image address = the upper 20 bits of the 32-bit KNC side physical
		 * address where the flash image resides
		 */
		offset = scratch2reg.bits.image_addr << 12 ;
		if (len == 0) {
			status = -EINVAL;
			goto exit;
		}

		if (len > (mic_ctx->aper.len - offset)) {
			status = -EINVAL;
			goto exit;
		}
		src = mic_ctx->aper.va + offset;

		temp = copy_to_user(data, src, len);
		if (temp > 0) {
			printk("error while copy to user \n");
			status = -EFAULT;
			goto exit;
		}
		break;

	case FLASH_CMD_ABORT:

		scratch1reg.bits.command = FLASH_CMD_ABORT;
		SBOX_WRITE(scratch1reg.value, mmio_va, SBOX_SCRATCH1);

		mic_send_bootstrap_intr(mic_ctx);
		break;

	case FLASH_CMD_VERSION:

		/*
		 * image address = the upper 20 bits of the 32-bit of scracth2 register
		 * is card side physical address where the flash image resides
		 */
		scratch2reg.bits.image_addr = RASMM_DEFAULT_OFFSET >> 12;
		SBOX_WRITE(scratch2reg.value, mmio_va, SBOX_SCRATCH2);

		/*
		 * flash version command : similar to read_data command.
		 * Instead of get_user_pages(), use kmalloc() as we are allocating
		 * buffer of lesser size
		 */
		scratch1reg.bits.command = FLASH_CMD_VERSION;
		SBOX_WRITE(scratch1reg.value, mmio_va, SBOX_SCRATCH1);

		mic_send_bootstrap_intr(mic_ctx);

		/* poll for completion */
		while(scratch1reg.bits.status != FLASH_CMD_COMPLETED) {
			ret = SBOX_READ(mmio_va, SBOX_SCRATCH1);
			scratch1reg.value = ret;
			msleep(1);
			i++;
			printk("Looping for status (time = %d ms)\n", i);
			if(i > 3000) {
				status = -ETIME;
				goto exit;
			}

		}

		src = mic_ctx->aper.va + RASMM_DEFAULT_OFFSET;

		if (len == 0) {
			status = -EINVAL;
			goto exit;
		}
		verbuf = kmalloc(len, GFP_KERNEL);
		if (!verbuf) {
			status = -ENOMEM;
			goto exit;
		}

		memcpy(verbuf, src, len);

		printk("header verbuf is : %x\n", verbuf->hdr_ver);
		printk("odm verbuf is : %x\n", verbuf->odm_ver);
		printk("uptd time bcd is : %llu\n", verbuf->upd_time_bcd);
		printk("updated verbuf is : %d\n", *((int*)(&verbuf->upd_ver)));
		printk("mfg time bcd is : %llu\n", verbuf->mfg_time_bcd);
		printk("mfg verbuf is : %d\n", *((int*)(&verbuf->mfg_ver)));

		temp = copy_to_user(data, verbuf, len);
		if(temp > 0) {
			printk("error while copy to user \n");
			status = -EFAULT;
			if(verbuf) {
				kfree(verbuf);
			}
			goto exit;
		}

		if(verbuf) {
			kfree(verbuf);
		}

		break;

	case FLASH_CMD_WRITE:

		/* flash write command : pin user pages for the data buffer which contains
		 * the image.
		 * For the write command, we provide the offset for writing.
		 * GTT is set to 64MB and offset = 0.
		 */
		if (len > (mic_ctx->aper.len - RASMM_DEFAULT_OFFSET)) {
			status = -EINVAL;
			goto exit;
		}
		src = mic_ctx->aper.va + RASMM_DEFAULT_OFFSET;
		if (len == 0) {
			status = -EINVAL;
			goto exit;
		}
		temp = copy_from_user(src, data, len);
		if (temp > 0) {
			printk("error while copying from user \n");
			status = -EFAULT;
			goto exit;
		}

		/* image address = the upper 20 bits of the 32-bit KNC side physical
		 * address where the flash image resides
		 */
		scratch2reg.bits.image_addr = RASMM_DEFAULT_OFFSET >> 12;
		SBOX_WRITE(scratch2reg.value, mmio_va, SBOX_SCRATCH2);

		scratch1reg.bits.command = FLASH_CMD_WRITE;
		SBOX_WRITE(scratch1reg.value, mmio_va, SBOX_SCRATCH1);

		mic_send_bootstrap_intr(mic_ctx);

	break;

	case RAS_CMD_CORE_DISABLE:
	case RAS_CMD_CORE_ENABLE:
		if (copy_from_user(&cmddata, data, sizeof(cmddata))) {
			status = -EFAULT;
			goto exit;
		}
		scratch1reg.bits.cmd_data = cmddata;
		if (cmddata > MAX_CORE_INDEX) {
			printk("Parameter given is greater than physical core index\n");
			status = -EINVAL;
			goto exit;
		}

	case RAS_CMD:
	case RAS_CMD_INJECT_REPAIR:
	case RAS_CMD_ECC_DISABLE:
	case RAS_CMD_ECC_ENABLE:
	case RAS_CMD_EXIT:
		do_gettimeofday(&t);
		SBOX_WRITE(t.tv_sec, mmio_va, SBOX_SCRATCH3);
		scratch1reg.bits.command = type;
		SBOX_WRITE(scratch1reg.value, mmio_va, SBOX_SCRATCH1);

		mic_send_bootstrap_intr(mic_ctx);

	break;

	case FLASH_CMD_STATUS:

		/* status command : mmio read of SCRATCH1 register
		 * The percentage completion is only updated on the
		 * Flash Write function as currently implemented.
		 * The other functions are expected to complete almost instantly
		 */
		if(len != sizeof(struct flash_stat)) {
			status = -EINVAL;
			goto exit;
		}
		if (len == 0) {
			status = -EINVAL;
			goto exit;
		}
		statbuf = kmalloc(len, GFP_KERNEL);
		if(!statbuf) {
			status = -ENOMEM;
			goto exit;
		}

		temp = SBOX_READ(mmio_va, SBOX_SCRATCH1);
		scratch1reg.value = (uint32_t)temp;

		statbuf->status = scratch1reg.bits.status;
		statbuf->percent = scratch1reg.bits.percent;
		statbuf->smc_status = scratch1reg.bits.smc_status;
		statbuf->cmd_data = scratch1reg.bits.cmd_data;
		statbuf->mm_debug = scratch1reg.bits.mm_debug;

		temp = copy_to_user(data, statbuf, len);
		if(temp > 0) {
			printk("Error copying data to user buffer\n");
			status = -EFAULT;
			if(statbuf) {
				kfree(statbuf);
			}
			goto exit;
		}

		if(statbuf) {
			kfree(statbuf);
		}

	break;

	default:
		printk(KERN_ERR "Unknown command\n");
		status = -EOPNOTSUPP;
	break;

	}

	exit :
	return status;
}