// SPDX-License-Identifier: GPL-2.0
/*
 * SH7760/SH7763 LCDC Framebuffer driver.
 *
 * (c) 2006-2008 MSC Vertriebsges.m.b.H.,
 *             Manuel Lauss <mano@roarinelk.homelinux.net>
 * (c) 2008 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
 *
 * PLEASE HAVE A LOOK AT Documentation/fb/sh7760fb.rst!
 *
 * Thanks to Siegfried Schaefer <s.schaefer at schaefer-edv.de>
 *     for his original source and testing!
 *
 * sh7760_setcolreg get from drivers/video/sh_mobile_lcdcfb.c
 */

#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/fb.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include <asm/sh7760fb.h>

struct sh7760fb_par {
	void __iomem *base;
	int irq;

	struct sh7760fb_platdata *pd;	/* display information */

	dma_addr_t fbdma;	/* physical address */

	int rot;		/* rotation enabled? */

	u32 pseudo_palette[16];

	struct platform_device *dev;
	struct resource *ioarea;
	struct completion vsync;	/* vsync irq event */
};

static irqreturn_t sh7760fb_irq(int irq, void *data)
{
	struct completion *c = data;

	complete(c);

	return IRQ_HANDLED;
}

/* wait_for_lps - wait until power supply has reached a certain state. */
static int wait_for_lps(struct sh7760fb_par *par, int val)
{
	int i = 100;
	while (--i && ((ioread16(par->base + LDPMMR) & 3) != val))
		msleep(1);

	if (i <= 0)
		return -ETIMEDOUT;

	return 0;
}

/* en/disable the LCDC */
static int sh7760fb_blank(int blank, struct fb_info *info)
{
	struct sh7760fb_par *par = info->par;
	struct sh7760fb_platdata *pd = par->pd;
	unsigned short cntr = ioread16(par->base + LDCNTR);
	unsigned short intr = ioread16(par->base + LDINTR);
	int lps;

	if (blank == FB_BLANK_UNBLANK) {
		intr |= VINT_START;
		cntr = LDCNTR_DON2 | LDCNTR_DON;
		lps = 3;
	} else {
		intr &= ~VINT_START;
		cntr = LDCNTR_DON2;
		lps = 0;
	}

	if (pd->blank)
		pd->blank(blank);

	iowrite16(intr, par->base + LDINTR);
	iowrite16(cntr, par->base + LDCNTR);

	return wait_for_lps(par, lps);
}

static int sh7760_setcolreg (u_int regno,
	u_int red, u_int green, u_int blue,
	u_int transp, struct fb_info *info)
{
	u32 *palette = info->pseudo_palette;

	if (regno >= 16)
		return -EINVAL;

	/* only FB_VISUAL_TRUECOLOR supported */

	red >>= 16 - info->var.red.length;
	green >>= 16 - info->var.green.length;
	blue >>= 16 - info->var.blue.length;
	transp >>= 16 - info->var.transp.length;

	palette[regno] = (red << info->var.red.offset) |
		(green << info->var.green.offset) |
		(blue << info->var.blue.offset) |
		(transp << info->var.transp.offset);

	return 0;
}

static int sh7760fb_get_color_info(struct fb_info *info,
				   u16 lddfr, int *bpp, int *gray)
{
	int lbpp, lgray;

	lgray = lbpp = 0;

	switch (lddfr & LDDFR_COLOR_MASK) {
	case LDDFR_1BPP_MONO:
		lgray = 1;
		lbpp = 1;
		break;
	case LDDFR_2BPP_MONO:
		lgray = 1;
		lbpp = 2;
		break;
	case LDDFR_4BPP_MONO:
		lgray = 1;
		fallthrough;
	case LDDFR_4BPP:
		lbpp = 4;
		break;
	case LDDFR_6BPP_MONO:
		lgray = 1;
		fallthrough;
	case LDDFR_8BPP:
		lbpp = 8;
		break;
	case LDDFR_16BPP_RGB555:
	case LDDFR_16BPP_RGB565:
		lbpp = 16;
		lgray = 0;
		break;
	default:
		fb_dbg(info, "unsupported LDDFR bit depth.\n");
		return -EINVAL;
	}

	if (bpp)
		*bpp = lbpp;
	if (gray)
		*gray = lgray;

	return 0;
}

static int sh7760fb_check_var(struct fb_var_screeninfo *var,
			      struct fb_info *info)
{
	struct fb_fix_screeninfo *fix = &info->fix;
	struct sh7760fb_par *par = info->par;
	int ret, bpp;

	/* get color info from register value */
	ret = sh7760fb_get_color_info(info, par->pd->lddfr, &bpp, NULL);
	if (ret)
		return ret;

	var->bits_per_pixel = bpp;

	if ((var->grayscale) && (var->bits_per_pixel == 1))
		fix->visual = FB_VISUAL_MONO10;
	else if (var->bits_per_pixel >= 15)
		fix->visual = FB_VISUAL_TRUECOLOR;
	else
		fix->visual = FB_VISUAL_PSEUDOCOLOR;

	/* TODO: add some more validation here */
	return 0;
}

/*
 * sh7760fb_set_par - set videomode.
 *
 * NOTE: The rotation, grayscale and DSTN codepaths are
 *     totally untested!
 */
static int sh7760fb_set_par(struct fb_info *info)
{
	struct sh7760fb_par *par = info->par;
	struct fb_videomode *vm = par->pd->def_mode;
	unsigned long sbase, dstn_off, ldsarl, stride;
	unsigned short hsynp, hsynw, htcn, hdcn;
	unsigned short vsynp, vsynw, vtln, vdln;
	unsigned short lddfr, ldmtr;
	int ret, bpp, gray;

	par->rot = par->pd->rotate;

	/* rotate only works with xres <= 320 */
	if (par->rot && (vm->xres > 320)) {
		fb_dbg(info, "rotation disabled due to display size\n");
		par->rot = 0;
	}

	/* calculate LCDC reg vals from display parameters */
	hsynp = vm->right_margin + vm->xres;
	hsynw = vm->hsync_len;
	htcn = vm->left_margin + hsynp + hsynw;
	hdcn = vm->xres;
	vsynp = vm->lower_margin + vm->yres;
	vsynw = vm->vsync_len;
	vtln = vm->upper_margin + vsynp + vsynw;
	vdln = vm->yres;

	/* get color info from register value */
	ret = sh7760fb_get_color_info(info, par->pd->lddfr, &bpp, &gray);
	if (ret)
		return ret;

	fb_dbg(info, "%dx%d %dbpp %s (orientation %s)\n", hdcn,
		vdln, bpp, gray ? "grayscale" : "color",
		par->rot ? "rotated" : "normal");

#ifdef CONFIG_CPU_LITTLE_ENDIAN
	lddfr = par->pd->lddfr | (1 << 8);
#else
	lddfr = par->pd->lddfr & ~(1 << 8);
#endif

	ldmtr = par->pd->ldmtr;

	if (!(vm->sync & FB_SYNC_HOR_HIGH_ACT))
		ldmtr |= LDMTR_CL1POL;
	if (!(vm->sync & FB_SYNC_VERT_HIGH_ACT))
		ldmtr |= LDMTR_FLMPOL;

	/* shut down LCDC before changing display parameters */
	sh7760fb_blank(FB_BLANK_POWERDOWN, info);

	iowrite16(par->pd->ldickr, par->base + LDICKR);	/* pixclock */
	iowrite16(ldmtr, par->base + LDMTR);	/* polarities */
	iowrite16(lddfr, par->base + LDDFR);	/* color/depth */
	iowrite16((par->rot ? 1 << 13 : 0), par->base + LDSMR);	/* rotate */
	iowrite16(par->pd->ldpmmr, par->base + LDPMMR);	/* Power Management */
	iowrite16(par->pd->ldpspr, par->base + LDPSPR);	/* Power Supply Ctrl */

	/* display resolution */
	iowrite16(((htcn >> 3) - 1) | (((hdcn >> 3) - 1) << 8),
		  par->base + LDHCNR);
	iowrite16(vdln - 1, par->base + LDVDLNR);
	iowrite16(vtln - 1, par->base + LDVTLNR);
	/* h/v sync signals */
	iowrite16((vsynp - 1) | ((vsynw - 1) << 12), par->base + LDVSYNR);
	iowrite16(((hsynp >> 3) - 1) | (((hsynw >> 3) - 1) << 12),
		  par->base + LDHSYNR);
	/* AC modulation sig */
	iowrite16(par->pd->ldaclnr, par->base + LDACLNR);

	stride = (par->rot) ? vtln : hdcn;
	if (!gray)
		stride *= (bpp + 7) >> 3;
	else {
		if (bpp == 1)
			stride >>= 3;
		else if (bpp == 2)
			stride >>= 2;
		else if (bpp == 4)
			stride >>= 1;
		/* 6 bpp == 8 bpp */
	}

	/* if rotated, stride must be power of 2 */
	if (par->rot) {
		unsigned long bit = 1 << 31;
		while (bit) {
			if (stride & bit)
				break;
			bit >>= 1;
		}
		if (stride & ~bit)
			stride = bit << 1;	/* not P-o-2, round up */
	}
	iowrite16(stride, par->base + LDLAOR);

	/* set display mem start address */
	sbase = (unsigned long)par->fbdma;
	if (par->rot)
		sbase += (hdcn - 1) * stride;

	iowrite32(sbase, par->base + LDSARU);

	/*
	 * for DSTN need to set address for lower half.
	 * I (mlau) don't know which address to set it to,
	 * so I guessed at (stride * yres/2).
	 */
	if (((ldmtr & 0x003f) >= LDMTR_DSTN_MONO_8) &&
	    ((ldmtr & 0x003f) <= LDMTR_DSTN_COLOR_16)) {

		fb_dbg(info, " ***** DSTN untested! *****\n");

		dstn_off = stride;
		if (par->rot)
			dstn_off *= hdcn >> 1;
		else
			dstn_off *= vdln >> 1;

		ldsarl = sbase + dstn_off;
	} else
		ldsarl = 0;

	iowrite32(ldsarl, par->base + LDSARL);	/* mem for lower half of DSTN */

	info->fix.line_length = stride;

	sh7760fb_check_var(&info->var, info);

	sh7760fb_blank(FB_BLANK_UNBLANK, info);	/* panel on! */

	fb_dbg(info, "hdcn  : %6d htcn  : %6d\n", hdcn, htcn);
	fb_dbg(info, "hsynw : %6d hsynp : %6d\n", hsynw, hsynp);
	fb_dbg(info, "vdln  : %6d vtln  : %6d\n", vdln, vtln);
	fb_dbg(info, "vsynw : %6d vsynp : %6d\n", vsynw, vsynp);
	fb_dbg(info, "clksrc: %6d clkdiv: %6d\n",
		(par->pd->ldickr >> 12) & 3, par->pd->ldickr & 0x1f);
	fb_dbg(info, "ldpmmr: 0x%04x ldpspr: 0x%04x\n", par->pd->ldpmmr,
		par->pd->ldpspr);
	fb_dbg(info, "ldmtr : 0x%04x lddfr : 0x%04x\n", ldmtr, lddfr);
	fb_dbg(info, "ldlaor: %ld\n", stride);
	fb_dbg(info, "ldsaru: 0x%08lx ldsarl: 0x%08lx\n", sbase, ldsarl);

	return 0;
}

static const struct fb_ops sh7760fb_ops = {
	.owner = THIS_MODULE,
	FB_DEFAULT_IOMEM_OPS,
	.fb_blank = sh7760fb_blank,
	.fb_check_var = sh7760fb_check_var,
	.fb_setcolreg = sh7760_setcolreg,
	.fb_set_par = sh7760fb_set_par,
};

static void sh7760fb_free_mem(struct fb_info *info)
{
	struct sh7760fb_par *par = info->par;

	if (!info->screen_base)
		return;

	dma_free_coherent(info->device, info->screen_size,
			  info->screen_base, par->fbdma);

	par->fbdma = 0;
	info->screen_base = NULL;
	info->screen_size = 0;
}

/* allocate the framebuffer memory. This memory must be in Area3,
 * (dictated by the DMA engine) and contiguous, at a 512 byte boundary.
 */
static int sh7760fb_alloc_mem(struct fb_info *info)
{
	struct sh7760fb_par *par = info->par;
	void *fbmem;
	unsigned long vram;
	int ret, bpp;

	if (info->screen_base)
		return 0;

	/* get color info from register value */
	ret = sh7760fb_get_color_info(info, par->pd->lddfr, &bpp, NULL);
	if (ret) {
		printk(KERN_ERR "colinfo\n");
		return ret;
	}

	/* min VRAM: xres_min = 16, yres_min = 1, bpp = 1: 2byte -> 1 page
	   max VRAM: xres_max = 1024, yres_max = 1024, bpp = 16: 2MB */

	vram = info->var.xres * info->var.yres;
	if (info->var.grayscale) {
		if (bpp == 1)
			vram >>= 3;
		else if (bpp == 2)
			vram >>= 2;
		else if (bpp == 4)
			vram >>= 1;
	} else if (bpp > 8)
		vram *= 2;
	if ((vram < 1) || (vram > 1024 * 2048)) {
		fb_dbg(info, "too much VRAM required. Check settings\n");
		return -ENODEV;
	}

	if (vram < PAGE_SIZE)
		vram = PAGE_SIZE;

	fbmem = dma_alloc_coherent(info->device, vram, &par->fbdma, GFP_KERNEL);

	if (!fbmem)
		return -ENOMEM;

	if ((par->fbdma & SH7760FB_DMA_MASK) != SH7760FB_DMA_MASK) {
		sh7760fb_free_mem(info);
		dev_err(info->device, "kernel gave me memory at 0x%08lx, which is"
			"unusable for the LCDC\n", (unsigned long)par->fbdma);
		return -ENOMEM;
	}

	info->screen_base = fbmem;
	info->screen_size = vram;
	info->fix.smem_start = (unsigned long)info->screen_base;
	info->fix.smem_len = info->screen_size;

	return 0;
}

static int sh7760fb_probe(struct platform_device *pdev)
{
	struct fb_info *info;
	struct resource *res;
	struct sh7760fb_par *par;
	int ret;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (unlikely(res == NULL)) {
		dev_err(&pdev->dev, "invalid resource\n");
		return -EINVAL;
	}

	info = framebuffer_alloc(sizeof(struct sh7760fb_par), &pdev->dev);
	if (!info)
		return -ENOMEM;

	par = info->par;
	par->dev = pdev;

	par->pd = pdev->dev.platform_data;
	if (!par->pd) {
		dev_dbg(&pdev->dev, "no display setup data!\n");
		ret = -ENODEV;
		goto out_fb;
	}

	par->ioarea = request_mem_region(res->start,
					 resource_size(res), pdev->name);
	if (!par->ioarea) {
		dev_err(&pdev->dev, "mmio area busy\n");
		ret = -EBUSY;
		goto out_fb;
	}

	par->base = ioremap(res->start, resource_size(res));
	if (!par->base) {
		dev_err(&pdev->dev, "cannot remap\n");
		ret = -ENODEV;
		goto out_res;
	}

	iowrite16(0, par->base + LDINTR);	/* disable vsync irq */
	par->irq = platform_get_irq(pdev, 0);
	if (par->irq >= 0) {
		ret = request_irq(par->irq, sh7760fb_irq, 0,
				  "sh7760-lcdc", &par->vsync);
		if (ret) {
			dev_err(&pdev->dev, "cannot grab IRQ\n");
			par->irq = -ENXIO;
		} else
			disable_irq_nosync(par->irq);
	}

	fb_videomode_to_var(&info->var, par->pd->def_mode);

	ret = sh7760fb_alloc_mem(info);
	if (ret) {
		dev_dbg(info->device, "framebuffer memory allocation failed!\n");
		goto out_unmap;
	}

	info->pseudo_palette = par->pseudo_palette;

	/* fixup color register bitpositions. These are fixed by hardware */
	info->var.red.offset = 11;
	info->var.red.length = 5;
	info->var.red.msb_right = 0;

	info->var.green.offset = 5;
	info->var.green.length = 6;
	info->var.green.msb_right = 0;

	info->var.blue.offset = 0;
	info->var.blue.length = 5;
	info->var.blue.msb_right = 0;

	info->var.transp.offset = 0;
	info->var.transp.length = 0;
	info->var.transp.msb_right = 0;

	strcpy(info->fix.id, "sh7760-lcdc");

	/* set the DON2 bit now, before cmap allocation, as it will randomize
	 * palette memory.
	 */
	iowrite16(LDCNTR_DON2, par->base + LDCNTR);
	info->fbops = &sh7760fb_ops;

	ret = fb_alloc_cmap(&info->cmap, 256, 0);
	if (ret) {
		dev_dbg(&pdev->dev, "Unable to allocate cmap memory\n");
		goto out_mem;
	}

	ret = register_framebuffer(info);
	if (ret < 0) {
		dev_dbg(&pdev->dev, "cannot register fb!\n");
		goto out_cmap;
	}
	platform_set_drvdata(pdev, info);

	printk(KERN_INFO "%s: memory at phys 0x%08lx-0x%08lx, size %ld KiB\n",
	       pdev->name,
	       (unsigned long)par->fbdma,
	       (unsigned long)(par->fbdma + info->screen_size - 1),
	       info->screen_size >> 10);

	return 0;

out_cmap:
	sh7760fb_blank(FB_BLANK_POWERDOWN, info);
	fb_dealloc_cmap(&info->cmap);
out_mem:
	sh7760fb_free_mem(info);
out_unmap:
	if (par->irq >= 0)
		free_irq(par->irq, &par->vsync);
	iounmap(par->base);
out_res:
	release_mem_region(res->start, resource_size(res));
out_fb:
	framebuffer_release(info);
	return ret;
}

static void sh7760fb_remove(struct platform_device *dev)
{
	struct fb_info *info = platform_get_drvdata(dev);
	struct sh7760fb_par *par = info->par;

	sh7760fb_blank(FB_BLANK_POWERDOWN, info);
	unregister_framebuffer(info);
	fb_dealloc_cmap(&info->cmap);
	sh7760fb_free_mem(info);
	if (par->irq >= 0)
		free_irq(par->irq, &par->vsync);
	iounmap(par->base);
	release_mem_region(par->ioarea->start, resource_size(par->ioarea));
	framebuffer_release(info);
}

static struct platform_driver sh7760_lcdc_driver = {
	.driver = {
		   .name = "sh7760-lcdc",
		   },
	.probe = sh7760fb_probe,
	.remove_new = sh7760fb_remove,
};

module_platform_driver(sh7760_lcdc_driver);

MODULE_AUTHOR("Nobuhiro Iwamatsu, Manuel Lauss");
MODULE_DESCRIPTION("FBdev for SH7760/63 integrated LCD Controller");
MODULE_LICENSE("GPL v2");
