/*
 * Probing flash chips with QINFO records.
 * (C) 2008 Korolev Alexey <akorolev@infradead.org>
 * (C) 2008 Vasiliy Leonenko <vasiliy.leonenko@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/interrupt.h>

#include <linux/mtd/xip.h>
#include <linux/mtd/map.h>
#include <linux/mtd/pfow.h>
#include <linux/mtd/qinfo.h>

static int lpddr_chip_setup(struct map_info *map, struct lpddr_private *lpddr);
struct mtd_info *lpddr_probe(struct map_info *map);
static struct lpddr_private *lpddr_probe_chip(struct map_info *map);
static int lpddr_pfow_present(struct map_info *map,
			struct lpddr_private *lpddr);

static struct qinfo_query_info qinfo_array[] = {
	/* General device info */
	{0, 0, "DevSizeShift", "Device size 2^n bytes"},
	{0, 3, "BufSizeShift", "Program buffer size 2^n bytes"},
	/* Erase block information */
	{1, 1, "TotalBlocksNum", "Total number of blocks"},
	{1, 2, "UniformBlockSizeShift", "Uniform block size 2^n bytes"},
	/* Partition information */
	{2, 1, "HWPartsNum", "Number of hardware partitions"},
	/* Optional features */
	{5, 1, "SuspEraseSupp", "Suspend erase supported"},
	/* Operation typical time */
	{10, 0, "SingleWordProgTime", "Single word program 2^n u-sec"},
	{10, 1, "ProgBufferTime", "Program buffer write 2^n u-sec"},
	{10, 2, "BlockEraseTime", "Block erase 2^n m-sec"},
	{10, 3, "FullChipEraseTime", "Full chip erase 2^n m-sec"},
};

static long lpddr_get_qinforec_pos(struct map_info *map, char *id_str)
{
	int qinfo_lines = ARRAY_SIZE(qinfo_array);
	int i;
	int bankwidth = map_bankwidth(map) * 8;
	int major, minor;

	for (i = 0; i < qinfo_lines; i++) {
		if (strcmp(id_str, qinfo_array[i].id_str) == 0) {
			major = qinfo_array[i].major & ((1 << bankwidth) - 1);
			minor = qinfo_array[i].minor & ((1 << bankwidth) - 1);
			return minor | (major << bankwidth);
		}
	}
	printk(KERN_ERR"%s qinfo id string is wrong! \n", map->name);
	BUG();
	return -1;
}

static uint16_t lpddr_info_query(struct map_info *map, char *id_str)
{
	unsigned int dsr, val;
	int bits_per_chip = map_bankwidth(map) * 8;
	unsigned long adr = lpddr_get_qinforec_pos(map, id_str);
	int attempts = 20;

	/* Write a request for the PFOW record */
	map_write(map, CMD(LPDDR_INFO_QUERY),
			map->pfow_base + PFOW_COMMAND_CODE);
	map_write(map, CMD(adr & ((1 << bits_per_chip) - 1)),
			map->pfow_base + PFOW_COMMAND_ADDRESS_L);
	map_write(map, CMD(adr >> bits_per_chip),
			map->pfow_base + PFOW_COMMAND_ADDRESS_H);
	map_write(map, CMD(LPDDR_START_EXECUTION),
			map->pfow_base + PFOW_COMMAND_EXECUTE);

	while ((attempts--) > 0) {
		dsr = CMDVAL(map_read(map, map->pfow_base + PFOW_DSR));
		if (dsr & DSR_READY_STATUS)
			break;
		udelay(10);
	}

	val = CMDVAL(map_read(map, map->pfow_base + PFOW_COMMAND_DATA));
	return val;
}

static int lpddr_pfow_present(struct map_info *map, struct lpddr_private *lpddr)
{
	map_word pfow_val[4];

	/* Check identification string */
	pfow_val[0] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_P);
	pfow_val[1] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_F);
	pfow_val[2] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_O);
	pfow_val[3] = map_read(map, map->pfow_base + PFOW_QUERY_STRING_W);

	if (!map_word_equal(map, CMD('P'), pfow_val[0]))
		goto out;

	if (!map_word_equal(map, CMD('F'), pfow_val[1]))
		goto out;

	if (!map_word_equal(map, CMD('O'), pfow_val[2]))
		goto out;

	if (!map_word_equal(map, CMD('W'), pfow_val[3]))
		goto out;

	return 1;	/* "PFOW" is found */
out:
	printk(KERN_WARNING"%s: PFOW string at 0x%lx is not found \n",
					map->name, map->pfow_base);
	return 0;
}

static int lpddr_chip_setup(struct map_info *map, struct lpddr_private *lpddr)
{

	lpddr->qinfo = kzalloc(sizeof(struct qinfo_chip), GFP_KERNEL);
	if (!lpddr->qinfo)
		return 0;

	/* Get the ManuID */
	lpddr->ManufactId = CMDVAL(map_read(map, map->pfow_base + PFOW_MANUFACTURER_ID));
	/* Get the DeviceID */
	lpddr->DevId = CMDVAL(map_read(map, map->pfow_base + PFOW_DEVICE_ID));
	/* read parameters from chip qinfo table */
	lpddr->qinfo->DevSizeShift = lpddr_info_query(map, "DevSizeShift");
	lpddr->qinfo->TotalBlocksNum = lpddr_info_query(map, "TotalBlocksNum");
	lpddr->qinfo->BufSizeShift = lpddr_info_query(map, "BufSizeShift");
	lpddr->qinfo->HWPartsNum = lpddr_info_query(map, "HWPartsNum");
	lpddr->qinfo->UniformBlockSizeShift =
				lpddr_info_query(map, "UniformBlockSizeShift");
	lpddr->qinfo->SuspEraseSupp = lpddr_info_query(map, "SuspEraseSupp");
	lpddr->qinfo->SingleWordProgTime =
				lpddr_info_query(map, "SingleWordProgTime");
	lpddr->qinfo->ProgBufferTime = lpddr_info_query(map, "ProgBufferTime");
	lpddr->qinfo->BlockEraseTime = lpddr_info_query(map, "BlockEraseTime");
	return 1;
}
static struct lpddr_private *lpddr_probe_chip(struct map_info *map)
{
	struct lpddr_private lpddr;
	struct lpddr_private *retlpddr;
	int numvirtchips;


	if ((map->pfow_base + 0x1000) >= map->size) {
		printk(KERN_NOTICE"%s Probe at base (0x%08lx) past the end of"
				"the map(0x%08lx)\n", map->name,
				(unsigned long)map->pfow_base, map->size - 1);
		return NULL;
	}
	memset(&lpddr, 0, sizeof(struct lpddr_private));
	if (!lpddr_pfow_present(map, &lpddr))
		return NULL;

	if (!lpddr_chip_setup(map, &lpddr))
		return NULL;

	/* Ok so we found a chip */
	lpddr.chipshift = lpddr.qinfo->DevSizeShift;
	lpddr.numchips = 1;

	numvirtchips = lpddr.numchips * lpddr.qinfo->HWPartsNum;
	retlpddr = kzalloc(struct_size(retlpddr, chips, numvirtchips),
			   GFP_KERNEL);
	if (!retlpddr)
		return NULL;

	memcpy(retlpddr, &lpddr, sizeof(struct lpddr_private));

	retlpddr->numchips = numvirtchips;
	retlpddr->chipshift = retlpddr->qinfo->DevSizeShift -
				__ffs(retlpddr->qinfo->HWPartsNum);

	return retlpddr;
}

struct mtd_info *lpddr_probe(struct map_info *map)
{
	struct mtd_info *mtd = NULL;
	struct lpddr_private *lpddr;

	/* First probe the map to see if we havecan open PFOW here */
	lpddr = lpddr_probe_chip(map);
	if (!lpddr)
		return NULL;

	map->fldrv_priv = lpddr;
	mtd = lpddr_cmdset(map);
	if (mtd) {
		if (mtd->size > map->size) {
			printk(KERN_WARNING "Reducing visibility of %ldKiB chip"
				"to %ldKiB\n", (unsigned long)mtd->size >> 10,
				(unsigned long)map->size >> 10);
			mtd->size = map->size;
		}
		return mtd;
	}

	kfree(lpddr->qinfo);
	kfree(lpddr);
	map->fldrv_priv = NULL;
	return NULL;
}

static struct mtd_chip_driver lpddr_chipdrv = {
	.probe		= lpddr_probe,
	.name		= "qinfo_probe",
	.module		= THIS_MODULE
};

static int __init lpddr_probe_init(void)
{
	register_mtd_chip_driver(&lpddr_chipdrv);
	return 0;
}

static void __exit lpddr_probe_exit(void)
{
	unregister_mtd_chip_driver(&lpddr_chipdrv);
}

module_init(lpddr_probe_init);
module_exit(lpddr_probe_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vasiliy Leonenko <vasiliy.leonenko@gmail.com>");
MODULE_DESCRIPTION("Driver to probe qinfo flash chips");

