/* 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 <asm/page.h>
#include <asm/pgtable.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) */
