/*
 *  cx18 firmware functions
 *
 *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
 *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
 *
 *  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.
 */

#include "cx18-driver.h"
#include "cx18-io.h"
#include "cx18-scb.h"
#include "cx18-irq.h"
#include "cx18-firmware.h"
#include "cx18-cards.h"
#include <linux/firmware.h>

#define CX18_PROC_SOFT_RESET		0xc70010
#define CX18_DDR_SOFT_RESET		0xc70014
#define CX18_CLOCK_SELECT1		0xc71000
#define CX18_CLOCK_SELECT2		0xc71004
#define CX18_HALF_CLOCK_SELECT1		0xc71008
#define CX18_HALF_CLOCK_SELECT2		0xc7100C
#define CX18_CLOCK_POLARITY1		0xc71010
#define CX18_CLOCK_POLARITY2		0xc71014
#define CX18_ADD_DELAY_ENABLE1		0xc71018
#define CX18_ADD_DELAY_ENABLE2		0xc7101C
#define CX18_CLOCK_ENABLE1		0xc71020
#define CX18_CLOCK_ENABLE2		0xc71024

#define CX18_REG_BUS_TIMEOUT_EN		0xc72024

#define CX18_FAST_CLOCK_PLL_INT		0xc78000
#define CX18_FAST_CLOCK_PLL_FRAC	0xc78004
#define CX18_FAST_CLOCK_PLL_POST	0xc78008
#define CX18_FAST_CLOCK_PLL_PRESCALE	0xc7800C
#define CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH 0xc78010

#define CX18_SLOW_CLOCK_PLL_INT		0xc78014
#define CX18_SLOW_CLOCK_PLL_FRAC	0xc78018
#define CX18_SLOW_CLOCK_PLL_POST	0xc7801C
#define CX18_MPEG_CLOCK_PLL_INT		0xc78040
#define CX18_MPEG_CLOCK_PLL_FRAC	0xc78044
#define CX18_MPEG_CLOCK_PLL_POST	0xc78048
#define CX18_PLL_POWER_DOWN		0xc78088
#define CX18_SW1_INT_STATUS             0xc73104
#define CX18_SW1_INT_ENABLE_PCI         0xc7311C
#define CX18_SW2_INT_SET                0xc73140
#define CX18_SW2_INT_STATUS             0xc73144
#define CX18_ADEC_CONTROL		0xc78120

#define CX18_DDR_REQUEST_ENABLE		0xc80000
#define CX18_DDR_CHIP_CONFIG		0xc80004
#define CX18_DDR_REFRESH		0xc80008
#define CX18_DDR_TIMING1		0xc8000C
#define CX18_DDR_TIMING2		0xc80010
#define CX18_DDR_POWER_REG		0xc8001C

#define CX18_DDR_TUNE_LANE		0xc80048
#define CX18_DDR_INITIAL_EMRS		0xc80054
#define CX18_DDR_MB_PER_ROW_7		0xc8009C
#define CX18_DDR_BASE_63_ADDR		0xc804FC

#define CX18_WMB_CLIENT02		0xc90108
#define CX18_WMB_CLIENT05		0xc90114
#define CX18_WMB_CLIENT06		0xc90118
#define CX18_WMB_CLIENT07		0xc9011C
#define CX18_WMB_CLIENT08		0xc90120
#define CX18_WMB_CLIENT09		0xc90124
#define CX18_WMB_CLIENT10		0xc90128
#define CX18_WMB_CLIENT11		0xc9012C
#define CX18_WMB_CLIENT12		0xc90130
#define CX18_WMB_CLIENT13		0xc90134
#define CX18_WMB_CLIENT14		0xc90138

#define CX18_DSP0_INTERRUPT_MASK	0xd0004C

#define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
#define APU_ROM_SYNC2 0x72646548 /* "rdeH" */

struct cx18_apu_rom_seghdr {
	u32 sync1;
	u32 sync2;
	u32 addr;
	u32 size;
};

static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
{
	const struct firmware *fw = NULL;
	int i, j;
	unsigned size;
	u32 __iomem *dst = (u32 __iomem *)mem;
	const u32 *src;

	if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
		CX18_ERR("Unable to open firmware %s\n", fn);
		CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
		return -ENOMEM;
	}

	src = (const u32 *)fw->data;

	for (i = 0; i < fw->size; i += 4096) {
		cx18_setup_page(cx, i);
		for (j = i; j < fw->size && j < i + 4096; j += 4) {
			/* no need for endianness conversion on the ppc */
			cx18_raw_writel(cx, *src, dst);
			if (cx18_raw_readl(cx, dst) != *src) {
				CX18_ERR("Mismatch at offset %x\n", i);
				release_firmware(fw);
				cx18_setup_page(cx, 0);
				return -EIO;
			}
			dst++;
			src++;
		}
	}
	if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
		CX18_INFO("loaded %s firmware (%zu bytes)\n", fn, fw->size);
	size = fw->size;
	release_firmware(fw);
	cx18_setup_page(cx, SCB_OFFSET);
	return size;
}

static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
				u32 *entry_addr)
{
	const struct firmware *fw = NULL;
	int i, j;
	unsigned size;
	const u32 *src;
	struct cx18_apu_rom_seghdr seghdr;
	const u8 *vers;
	u32 offset = 0;
	u32 apu_version = 0;
	int sz;

	if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
		CX18_ERR("unable to open firmware %s\n", fn);
		CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
		cx18_setup_page(cx, 0);
		return -ENOMEM;
	}

	*entry_addr = 0;
	src = (const u32 *)fw->data;
	vers = fw->data + sizeof(seghdr);
	sz = fw->size;

	apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32];
	while (offset + sizeof(seghdr) < fw->size) {
		const __le32 *shptr = (__force __le32 *)src + offset / 4;

		seghdr.sync1 = le32_to_cpu(shptr[0]);
		seghdr.sync2 = le32_to_cpu(shptr[1]);
		seghdr.addr = le32_to_cpu(shptr[2]);
		seghdr.size = le32_to_cpu(shptr[3]);

		offset += sizeof(seghdr);
		if (seghdr.sync1 != APU_ROM_SYNC1 ||
		    seghdr.sync2 != APU_ROM_SYNC2) {
			offset += seghdr.size;
			continue;
		}
		CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr,
				seghdr.addr + seghdr.size - 1);
		if (*entry_addr == 0)
			*entry_addr = seghdr.addr;
		if (offset + seghdr.size > sz)
			break;
		for (i = 0; i < seghdr.size; i += 4096) {
			cx18_setup_page(cx, seghdr.addr + i);
			for (j = i; j < seghdr.size && j < i + 4096; j += 4) {
				/* no need for endianness conversion on the ppc */
				cx18_raw_writel(cx, src[(offset + j) / 4],
						dst + seghdr.addr + j);
				if (cx18_raw_readl(cx, dst + seghdr.addr + j)
				    != src[(offset + j) / 4]) {
					CX18_ERR("Mismatch at offset %x\n",
						 offset + j);
					release_firmware(fw);
					cx18_setup_page(cx, 0);
					return -EIO;
				}
			}
		}
		offset += seghdr.size;
	}
	if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags))
		CX18_INFO("loaded %s firmware V%08x (%zu bytes)\n",
				fn, apu_version, fw->size);
	size = fw->size;
	release_firmware(fw);
	cx18_setup_page(cx, 0);
	return size;
}

void cx18_halt_firmware(struct cx18 *cx)
{
	CX18_DEBUG_INFO("Preparing for firmware halt.\n");
	cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
				  0x0000000F, 0x000F000F);
	cx18_write_reg_expect(cx, 0x00020002, CX18_ADEC_CONTROL,
				  0x00000002, 0x00020002);
}

void cx18_init_power(struct cx18 *cx, int lowpwr)
{
	/* power-down Spare and AOM PLLs */
	/* power-up fast, slow and mpeg PLLs */
	cx18_write_reg(cx, 0x00000008, CX18_PLL_POWER_DOWN);

	/* ADEC out of sleep */
	cx18_write_reg_expect(cx, 0x00020000, CX18_ADEC_CONTROL,
				  0x00000000, 0x00020002);

	/*
	 * The PLL parameters are based on the external crystal frequency that
	 * would ideally be:
	 *
	 * NTSC Color subcarrier freq * 8 =
	 *	4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
	 *
	 * The accidents of history and rationale that explain from where this
	 * combination of magic numbers originate can be found in:
	 *
	 * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in
	 * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80
	 *
	 * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the
	 * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83
	 *
	 * As Mike Bradley has rightly pointed out, it's not the exact crystal
	 * frequency that matters, only that all parts of the driver and
	 * firmware are using the same value (close to the ideal value).
	 *
	 * Since I have a strong suspicion that, if the firmware ever assumes a
	 * crystal value at all, it will assume 28.636360 MHz, the crystal
	 * freq used in calculations in this driver will be:
	 *
	 *	xtal_freq = 28.636360 MHz
	 *
	 * an error of less than 0.13 ppm which is way, way better than any off
	 * the shelf crystal will have for accuracy anyway.
	 *
	 * Below I aim to run the PLLs' VCOs near 400 MHz to minimze errors.
	 *
	 * Many thanks to Jeff Campbell and Mike Bradley for their extensive
	 * investigation, experimentation, testing, and suggested solutions of
	 * of audio/video sync problems with SVideo and CVBS captures.
	 */

	/* the fast clock is at 200/245 MHz */
	/* 1 * xtal_freq * 0x0d.f7df9b8 / 2 = 200 MHz: 400 MHz pre post-divide*/
	/* 1 * xtal_freq * 0x11.1c71eb8 / 2 = 245 MHz: 490 MHz pre post-divide*/
	cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT);
	cx18_write_reg(cx, lowpwr ? 0x1EFBF37 : 0x038E3D7,
						CX18_FAST_CLOCK_PLL_FRAC);

	cx18_write_reg(cx, 2, CX18_FAST_CLOCK_PLL_POST);
	cx18_write_reg(cx, 1, CX18_FAST_CLOCK_PLL_PRESCALE);
	cx18_write_reg(cx, 4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH);

	/* set slow clock to 125/120 MHz */
	/* xtal_freq * 0x0d.1861a20 / 3 = 125 MHz: 375 MHz before post-divide */
	/* xtal_freq * 0x0c.92493f8 / 3 = 120 MHz: 360 MHz before post-divide */
	cx18_write_reg(cx, lowpwr ? 0xD : 0xC, CX18_SLOW_CLOCK_PLL_INT);
	cx18_write_reg(cx, lowpwr ? 0x30C344 : 0x124927F,
						CX18_SLOW_CLOCK_PLL_FRAC);
	cx18_write_reg(cx, 3, CX18_SLOW_CLOCK_PLL_POST);

	/* mpeg clock pll 54MHz */
	/* xtal_freq * 0xf.15f17f0 / 8 = 54 MHz: 432 MHz before post-divide */
	cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT);
	cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC);
	cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);

	/* Defaults */
	/* APU = SC or SC/2 = 125/62.5 */
	/* EPU = SC = 125 */
	/* DDR = FC = 180 */
	/* ENC = SC = 125 */
	/* AI1 = SC = 125 */
	/* VIM2 = disabled */
	/* PCI = FC/2 = 90 */
	/* AI2 = disabled */
	/* DEMUX = disabled */
	/* AO = SC/2 = 62.5 */
	/* SER = 54MHz */
	/* VFC = disabled */
	/* USB = disabled */

	if (lowpwr) {
		cx18_write_reg_expect(cx, 0xFFFF0020, CX18_CLOCK_SELECT1,
					  0x00000020, 0xFFFFFFFF);
		cx18_write_reg_expect(cx, 0xFFFF0004, CX18_CLOCK_SELECT2,
					  0x00000004, 0xFFFFFFFF);
	} else {
		/* This doesn't explicitly set every clock select */
		cx18_write_reg_expect(cx, 0x00060004, CX18_CLOCK_SELECT1,
					  0x00000004, 0x00060006);
		cx18_write_reg_expect(cx, 0x00060006, CX18_CLOCK_SELECT2,
					  0x00000006, 0x00060006);
	}

	cx18_write_reg_expect(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1,
				  0x00000002, 0xFFFFFFFF);
	cx18_write_reg_expect(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2,
				  0x00000104, 0xFFFFFFFF);
	cx18_write_reg_expect(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1,
				  0x00009026, 0xFFFFFFFF);
	cx18_write_reg_expect(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2,
				  0x00003105, 0xFFFFFFFF);
}

void cx18_init_memory(struct cx18 *cx)
{
	cx18_msleep_timeout(10, 0);
	cx18_write_reg_expect(cx, 0x00010000, CX18_DDR_SOFT_RESET,
				  0x00000000, 0x00010001);
	cx18_msleep_timeout(10, 0);

	cx18_write_reg(cx, cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG);

	cx18_msleep_timeout(10, 0);

	cx18_write_reg(cx, cx->card->ddr.refresh, CX18_DDR_REFRESH);
	cx18_write_reg(cx, cx->card->ddr.timing1, CX18_DDR_TIMING1);
	cx18_write_reg(cx, cx->card->ddr.timing2, CX18_DDR_TIMING2);

	cx18_msleep_timeout(10, 0);

	/* Initialize DQS pad time */
	cx18_write_reg(cx, cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE);
	cx18_write_reg(cx, cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS);

	cx18_msleep_timeout(10, 0);

	cx18_write_reg_expect(cx, 0x00020000, CX18_DDR_SOFT_RESET,
				  0x00000000, 0x00020002);
	cx18_msleep_timeout(10, 0);

	/* use power-down mode when idle */
	cx18_write_reg(cx, 0x00000010, CX18_DDR_POWER_REG);

	cx18_write_reg_expect(cx, 0x00010001, CX18_REG_BUS_TIMEOUT_EN,
				  0x00000001, 0x00010001);

	cx18_write_reg(cx, 0x48, CX18_DDR_MB_PER_ROW_7);
	cx18_write_reg(cx, 0xE0000, CX18_DDR_BASE_63_ADDR);

	cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT02);  /* AO */
	cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT09);  /* AI2 */
	cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT05);  /* VIM1 */
	cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT06);  /* AI1 */
	cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT07);  /* 3D comb */
	cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT10);  /* ME */
	cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT12);  /* ENC */
	cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT13);  /* PK */
	cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT11);  /* RC */
	cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT14);  /* AVO */
}

#define CX18_CPU_FIRMWARE "v4l-cx23418-cpu.fw"
#define CX18_APU_FIRMWARE "v4l-cx23418-apu.fw"

int cx18_firmware_init(struct cx18 *cx)
{
	u32 fw_entry_addr;
	int sz, retries;
	u32 api_args[MAX_MB_ARGUMENTS];

	/* Allow chip to control CLKRUN */
	cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK);

	/* Stop the firmware */
	cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET,
				  0x0000000F, 0x000F000F);

	cx18_msleep_timeout(1, 0);

	/* If the CPU is still running */
	if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) == 0) {
		CX18_ERR("%s: couldn't stop CPU to load firmware\n", __func__);
		return -EIO;
	}

	cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU);
	cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);

	sz = load_cpu_fw_direct(CX18_CPU_FIRMWARE, cx->enc_mem, cx);
	if (sz <= 0)
		return sz;

	/* The SCB & IPC area *must* be correct before starting the firmwares */
	cx18_init_scb(cx);

	fw_entry_addr = 0;
	sz = load_apu_fw_direct(CX18_APU_FIRMWARE, cx->enc_mem, cx,
				&fw_entry_addr);
	if (sz <= 0)
		return sz;

	/* Start the CPU. The CPU will take care of the APU for us. */
	cx18_write_reg_expect(cx, 0x00080000, CX18_PROC_SOFT_RESET,
				  0x00000000, 0x00080008);

	/* Wait up to 500 ms for the APU to come out of reset */
	for (retries = 0;
	     retries < 50 && (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1;
	     retries++)
		cx18_msleep_timeout(10, 0);

	cx18_msleep_timeout(200, 0);

	if (retries == 50 &&
	    (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1) {
		CX18_ERR("Could not start the CPU\n");
		return -EIO;
	}

	/*
	 * The CPU had once before set up to receive an interrupt for it's
	 * outgoing IRQ_CPU_TO_EPU_ACK to us.  If it ever does this, we get an
	 * interrupt when it sends us an ack, but by the time we process it,
	 * that flag in the SW2 status register has been cleared by the CPU
	 * firmware.  We'll prevent that not so useful condition from happening
	 * by clearing the CPU's interrupt enables for Ack IRQ's we want to
	 * process.
	 */
	cx18_sw2_irq_disable_cpu(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK);

	/* Try a benign command to see if the CPU is alive and well */
	sz = cx18_vapi_result(cx, api_args, CX18_CPU_DEBUG_PEEK32, 1, 0);
	if (sz < 0)
		return sz;

	/* initialize GPIO */
	cx18_write_reg_expect(cx, 0x14001400, 0xc78110, 0x00001400, 0x14001400);
	return 0;
}

MODULE_FIRMWARE(CX18_CPU_FIRMWARE);
MODULE_FIRMWARE(CX18_APU_FIRMWARE);
