Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  Copyright (C) 1995-2000  Linus Torvalds & author (see below)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  HT-6560B EIDE-controller support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *  To activate controller support use kernel parameter "ide0=ht6560b".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *  Use hdparm utility to enable PIO mode support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *  Author:    Mikko Ala-Fossi            <maf@iki.fi>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *             Jan Evert van Grootheest   <j.e.van.grootheest@caiway.nl>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define DRV_NAME	"ht6560b"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define HT6560B_VERSION "v0.08"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/ide.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /* #define DEBUG */  /* remove comments for DEBUG messages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * The special i/o-port that HT-6560B uses to configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  *    bit0 (0x01): "1" selects secondary interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  *    bit2 (0x04): "1" enables FIFO function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  *    bit5 (0x20): "1" enables prefetched data read function  (???)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * The special i/o-port that HT-6560A uses to configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *    bit0 (0x01): "1" selects secondary interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  *    bit1 (0x02): "1" enables prefetched data read function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  *    bit2 (0x04): "0" enables multi-master system	      (?)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  *    bit3 (0x08): "1" 3 cycle time, "0" 2 cycle time	      (?)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define HT_CONFIG_PORT	  0x3e6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static inline u8 HT_CONFIG(ide_drive_t *drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	return ((unsigned long)ide_get_drivedata(drive) & 0xff00) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * FIFO + PREFETCH (both a/b-model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define HT_CONFIG_DEFAULT 0x1c /* no prefetch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) /* #define HT_CONFIG_DEFAULT 0x3c */ /* with prefetch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define HT_SECONDARY_IF	  0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define HT_PREFETCH_MODE  0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * ht6560b Timing values:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * I reviewed some assembler source listings of htide drivers and found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  * out how they setup those cycle time interfacing values, as they at Holtek
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * call them. IDESETUP.COM that is supplied with the drivers figures out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * optimal values and fetches those values to drivers. I found out that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * they use Select register to fetch timings to the ide board right after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  * interface switching. After that it was quite easy to add code to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * ht6560b.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * IDESETUP.COM gave me values 0x24, 0x45, 0xaa, 0xff that worked fine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * for hda and hdc. But hdb needed higher values to work, so I guess
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * that sometimes it is necessary to give higher value than IDESETUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * gives.   [see cmd640.c for an extreme example of this. -ml]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * Perhaps I should explain something about these timing values:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * The higher nibble of value is the Recovery Time  (rt) and the lower nibble
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * of the value is the Active Time  (at). Minimum value 2 is the fastest and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  * the maximum value 15 is the slowest. Default values should be 15 for both.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * So 0x24 means 2 for rt and 4 for at. Each of the drives should have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  * both values, and IDESETUP gives automatically rt=15 st=15 for CDROMs or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * similar. If value is too small there will be all sorts of failures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  * Timing byte consists of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  *	High nibble:  Recovery Cycle Time  (rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  *	     The valid values range from 2 to 15. The default is 15.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  *	Low nibble:   Active Cycle Time	   (at)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  *	     The valid values range from 2 to 15. The default is 15.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * You can obtain optimized timing values by running Holtek IDESETUP.COM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  * for DOS. DOS drivers get their timing values from command line, where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  * the first value is the Recovery Time and the second value is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * Active Time for each drive. Smaller value gives higher speed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  * In case of failures you should probably fall back to a higher value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) static inline u8 HT_TIMING(ide_drive_t *drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	return (unsigned long)ide_get_drivedata(drive) & 0x00ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define HT_TIMING_DEFAULT 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  * This routine handles interface switching for the peculiar hardware design
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  * on the F.G.I./Holtek HT-6560B VLB IDE interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  * The HT-6560B can only enable one IDE port at a time, and requires a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * silly sequence (below) whenever we switch between primary and secondary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * This routine is invoked from ide.c to prepare for access to a given drive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void ht6560b_dev_select(ide_drive_t *drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	ide_hwif_t *hwif = drive->hwif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	static u8 current_select = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	static u8 current_timing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	u8 select, timing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	select = HT_CONFIG(drive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	timing = HT_TIMING(drive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	 * Need to enforce prefetch sometimes because otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	 * it'll hang (hard).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	if (drive->media != ide_disk ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	    (drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		select |= HT_PREFETCH_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	if (select != current_select || timing != current_timing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		current_select = select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		current_timing = timing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		(void)inb(HT_CONFIG_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		(void)inb(HT_CONFIG_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		(void)inb(HT_CONFIG_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		(void)inb(HT_CONFIG_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		outb(select, HT_CONFIG_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		 * Set timing for this drive:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		outb(timing, hwif->io_ports.device_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		(void)inb(hwif->io_ports.status_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		printk("ht6560b: %s: select=%#x timing=%#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			drive->name, select, timing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	outb(drive->select | ATA_DEVICE_OBS, hwif->io_ports.device_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  * Autodetection and initialization of ht6560b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int __init try_to_init_ht6560b(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	u8 orig_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	/* Autodetect ht6560b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	if ((orig_value = inb(HT_CONFIG_PORT)) == 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	for (i=3;i>0;i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		outb(0x00, HT_CONFIG_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		if (!( (~inb(HT_CONFIG_PORT)) & 0x3f )) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 			outb(orig_value, HT_CONFIG_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	outb(0x00, HT_CONFIG_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	if ((~inb(HT_CONFIG_PORT))& 0x3f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		outb(orig_value, HT_CONFIG_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	 * Ht6560b autodetected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	outb(HT_CONFIG_DEFAULT, HT_CONFIG_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	outb(HT_TIMING_DEFAULT, 0x1f6);	/* Select register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	(void)inb(0x1f7);		/* Status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	printk("ht6560b " HT6560B_VERSION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	       ": chipset detected and initialized"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	       " with debug enabled"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	       "\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	int active_time, recovery_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	int active_cycles, recovery_cycles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)         if (pio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		unsigned int cycle_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		cycle_time = ide_pio_cycle_time(drive, pio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		 *  Just like opti621.c we try to calculate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		 *  actual cycle time for recovery and activity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		 *  according system bus speed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		active_time = t->active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		recovery_time = cycle_time - active_time - t->setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		 *  Cycle times should be Vesa bus cycles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		active_cycles   = (active_time   * bus_speed + 999) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		recovery_cycles = (recovery_time * bus_speed + 999) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		 *  Upper and lower limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		if (active_cycles   < 2)  active_cycles   = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		if (recovery_cycles < 2)  recovery_cycles = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		if (active_cycles   > 15) active_cycles   = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		if (recovery_cycles > 15) recovery_cycles = 0;  /* 0==16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		printk("ht6560b: drive %s setting pio=%d recovery=%d (%dns) active=%d (%dns)\n", drive->name, pio, recovery_cycles, recovery_time, active_cycles, active_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		return (u8)((recovery_cycles << 4) | active_cycles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		printk("ht6560b: drive %s setting pio=0\n", drive->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		return HT_TIMING_DEFAULT;    /* default setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static DEFINE_SPINLOCK(ht6560b_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  *  Enable/Disable so called prefetch mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static void ht_set_prefetch(ide_drive_t *drive, u8 state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	unsigned long flags, config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	int t = HT_PREFETCH_MODE << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	spin_lock_irqsave(&ht6560b_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	config = (unsigned long)ide_get_drivedata(drive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	 *  Prefetch mode and unmask irq seems to conflict
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		config |= t;   /* enable prefetch mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		drive->dev_flags |= IDE_DFLAG_NO_UNMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		drive->dev_flags &= ~IDE_DFLAG_UNMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		config &= ~t;  /* disable prefetch mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	ide_set_drivedata(drive, (void *)config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	spin_unlock_irqrestore(&ht6560b_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static void ht6560b_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	unsigned long flags, config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	const u8 pio = drive->pio_mode - XFER_PIO_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	u8 timing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	switch (pio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	case 8:         /* set prefetch off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	case 9:         /* set prefetch on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		ht_set_prefetch(drive, pio & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	timing = ht_pio2timings(drive, pio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	spin_lock_irqsave(&ht6560b_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	config = (unsigned long)ide_get_drivedata(drive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	config &= 0xff00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	config |= timing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	ide_set_drivedata(drive, (void *)config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	spin_unlock_irqrestore(&ht6560b_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static void __init ht6560b_init_dev(ide_drive_t *drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	ide_hwif_t *hwif = drive->hwif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	/* Setting default configurations for drives. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	unsigned long t = (HT_CONFIG_DEFAULT << 8) | HT_TIMING_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	if (hwif->channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		t |= (HT_SECONDARY_IF << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	ide_set_drivedata(drive, (void *)t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static bool probe_ht6560b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) module_param_named(probe, probe_ht6560b, bool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static const struct ide_tp_ops ht6560b_tp_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	.exec_command		= ide_exec_command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	.read_status		= ide_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	.read_altstatus		= ide_read_altstatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	.write_devctl		= ide_write_devctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	.dev_select		= ht6560b_dev_select,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	.tf_load		= ide_tf_load,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	.tf_read		= ide_tf_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	.input_data		= ide_input_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	.output_data		= ide_output_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static const struct ide_port_ops ht6560b_port_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	.init_dev		= ht6560b_init_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	.set_pio_mode		= ht6560b_set_pio_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static const struct ide_port_info ht6560b_port_info __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	.name			= DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	.chipset		= ide_ht6560b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	.tp_ops 		= &ht6560b_tp_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	.port_ops		= &ht6560b_port_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	.host_flags		= IDE_HFLAG_SERIALIZE | /* is this needed? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 				  IDE_HFLAG_NO_DMA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 				  IDE_HFLAG_ABUSE_PREFETCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	.pio_mask		= ATA_PIO4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static int __init ht6560b_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if (probe_ht6560b == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	if (!request_region(HT_CONFIG_PORT, 1, DRV_NAME)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	if (!try_to_init_ht6560b()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		printk(KERN_NOTICE "%s: HBA not found\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		goto release_region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	return ide_legacy_device_add(&ht6560b_port_info, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) release_region:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	release_region(HT_CONFIG_PORT, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) module_init(ht6560b_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) MODULE_AUTHOR("See Local File");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) MODULE_DESCRIPTION("HT-6560B EIDE-controller support");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) MODULE_LICENSE("GPL");