/* SPDX-License-Identifier: GPL-2.0 */
/* sun3xflop.h: Sun3/80 specific parts of the floppy driver.
 *
 * Derived partially from asm-sparc/floppy.h, which is:
 *     Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
 *
 * Sun3x version 2/4/2000 Sam Creasey (sammy@sammy.net)
 */

#ifndef __ASM_SUN3X_FLOPPY_H
#define __ASM_SUN3X_FLOPPY_H

#include <linux/pgtable.h>
#include <asm/page.h>
#include <asm/irq.h>
#include <asm/sun3x.h>

/* default interrupt vector */
#define SUN3X_FDC_IRQ 0x40

/* some constants */
#define FCR_TC 0x1
#define FCR_EJECT 0x2
#define FCR_MTRON 0x4
#define FCR_DSEL1 0x8
#define FCR_DSEL0 0x10

/* We don't need no stinkin' I/O port allocation crap. */
#undef release_region
#undef request_region
#define release_region(X, Y)	do { } while(0)
#define request_region(X, Y, Z)	(1)

struct sun3xflop_private {
	volatile unsigned char *status_r;
	volatile unsigned char *data_r;
	volatile unsigned char *fcr_r;
	volatile unsigned char *fvr_r;
	unsigned char fcr;
} sun3x_fdc;

/* Super paranoid... */
#undef HAVE_DISABLE_HLT

/* Routines unique to each controller type on a Sun. */
static unsigned char sun3x_82072_fd_inb(int port)
{
	static int once = 0;
//	udelay(5);
	switch(port & 7) {
	default:
		pr_crit("floppy: Asked to read unknown port %d\n", port);
		panic("floppy: Port bolixed.");
	case 4: /* FD_STATUS */
		return (*sun3x_fdc.status_r) & ~STATUS_DMA;
	case 5: /* FD_DATA */
		return (*sun3x_fdc.data_r);
	case 7: /* FD_DIR */
		/* ugly hack, I can't find a way to actually detect the disk */
		if(!once) {
			once = 1;
			return 0x80;
		}
		return 0;
	};
	panic("sun_82072_fd_inb: How did I get here?");
}

static void sun3x_82072_fd_outb(unsigned char value, int port)
{
//	udelay(5);
	switch(port & 7) {
	default:
		pr_crit("floppy: Asked to write to unknown port %d\n", port);
		panic("floppy: Port bolixed.");
	case 2: /* FD_DOR */
		/* Oh geese, 82072 on the Sun has no DOR register,
		 * so we make do with taunting the FCR.
		 *
		 * ASSUMPTIONS:  There will only ever be one floppy
		 *               drive attached to a Sun controller
		 *               and it will be at drive zero.
		 */

	{
		unsigned char fcr = sun3x_fdc.fcr;

		if(value & 0x10) {
			fcr |= (FCR_DSEL0 | FCR_MTRON);
		} else
			fcr &= ~(FCR_DSEL0 | FCR_MTRON);


		if(fcr != sun3x_fdc.fcr) {
			*(sun3x_fdc.fcr_r) = fcr;
			sun3x_fdc.fcr = fcr;
		}
	}
		break;
	case 5: /* FD_DATA */
		*(sun3x_fdc.data_r) = value;
		break;
	case 7: /* FD_DCR */
		*(sun3x_fdc.status_r) = value;
		break;
	case 4: /* FD_STATUS */
		*(sun3x_fdc.status_r) = value;
		break;
	}
	return;
}


asmlinkage irqreturn_t sun3xflop_hardint(int irq, void *dev_id)
{
	register unsigned char st;

#undef TRACE_FLPY_INT
#define NO_FLOPPY_ASSEMBLER

#ifdef TRACE_FLPY_INT
	static int calls=0;
	static int bytes=0;
	static int dma_wait=0;
#endif
	if(!doing_pdma) {
		floppy_interrupt(irq, dev_id);
		return IRQ_HANDLED;
	}

//	pr_info("doing pdma\n");// st %x\n", sun_fdc->status_82072);

#ifdef TRACE_FLPY_INT
	if(!calls)
		bytes = virtual_dma_count;
#endif

	{
		register int lcount;
		register char *lptr;

		for(lcount=virtual_dma_count, lptr=virtual_dma_addr;
		    lcount; lcount--, lptr++) {
/*			st=fd_inb(virtual_dma_port+4) & 0x80 ;  */
			st = *(sun3x_fdc.status_r);
/*			if(st != 0xa0)                  */
/*				break;                  */

			if((st & 0x80) == 0) {
				virtual_dma_count = lcount;
				virtual_dma_addr = lptr;
				return IRQ_HANDLED;
			}

			if((st & 0x20) == 0)
				break;

			if(virtual_dma_mode)
/*				fd_outb(*lptr, virtual_dma_port+5); */
				*(sun3x_fdc.data_r) = *lptr;
			else
/*				*lptr = fd_inb(virtual_dma_port+5); */
				*lptr = *(sun3x_fdc.data_r);
		}

		virtual_dma_count = lcount;
		virtual_dma_addr = lptr;
/*		st = fd_inb(virtual_dma_port+4);   */
		st = *(sun3x_fdc.status_r);
	}

#ifdef TRACE_FLPY_INT
	calls++;
#endif
//	pr_info("st=%02x\n", st);
	if(st == 0x20)
		return IRQ_HANDLED;
	if(!(st & 0x20)) {
		virtual_dma_residue += virtual_dma_count;
		virtual_dma_count=0;
		doing_pdma = 0;

#ifdef TRACE_FLPY_INT
		pr_info("count=%x, residue=%x calls=%d bytes=%x dma_wait=%d\n",
			virtual_dma_count, virtual_dma_residue, calls, bytes,
			dma_wait);
		calls = 0;
		dma_wait=0;
#endif

		floppy_interrupt(irq, dev_id);
		return IRQ_HANDLED;
	}


#ifdef TRACE_FLPY_INT
	if(!virtual_dma_count)
		dma_wait++;
#endif
	return IRQ_HANDLED;
}

static int sun3xflop_request_irq(void)
{
	static int once = 0;
	int error;

	if(!once) {
		once = 1;
		error = request_irq(FLOPPY_IRQ, sun3xflop_hardint,
				    0, "floppy", NULL);
		return ((error == 0) ? 0 : -1);
	} else return 0;
}

static void __init floppy_set_flags(int *ints,int param, int param2);

static int sun3xflop_init(void)
{
	if(FLOPPY_IRQ < 0x40)
		FLOPPY_IRQ = SUN3X_FDC_IRQ;

	sun3x_fdc.status_r = (volatile unsigned char *)SUN3X_FDC;
	sun3x_fdc.data_r  = (volatile unsigned char *)(SUN3X_FDC+1);
	sun3x_fdc.fcr_r = (volatile unsigned char *)SUN3X_FDC_FCR;
	sun3x_fdc.fvr_r = (volatile unsigned char *)SUN3X_FDC_FVR;
	sun3x_fdc.fcr = 0;

	/* Last minute sanity check... */
	if(*sun3x_fdc.status_r == 0xff) {
		return -1;
	}

	*sun3x_fdc.fvr_r = FLOPPY_IRQ;

	*sun3x_fdc.fcr_r = FCR_TC;
	udelay(10);
	*sun3x_fdc.fcr_r = 0;

	/* Success... */
	floppy_set_flags(NULL, 1, FD_BROKEN_DCL); // I don't know how to detect this.
	allowed_drive_mask = 0x01;
	return (int) SUN3X_FDC;
}

/* I'm not precisely sure this eject routine works */
static int sun3x_eject(void)
{
	if(MACH_IS_SUN3X) {

		sun3x_fdc.fcr |= (FCR_DSEL0 | FCR_EJECT);
		*(sun3x_fdc.fcr_r) = sun3x_fdc.fcr;
		udelay(10);
		sun3x_fdc.fcr &= ~(FCR_DSEL0 | FCR_EJECT);
		*(sun3x_fdc.fcr_r) = sun3x_fdc.fcr;
	}

	return 0;
}

#define fd_eject(drive) sun3x_eject()

#endif /* !(__ASM_SUN3X_FLOPPY_H) */
