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-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Palmchip bk3710 IDE controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2006 Texas Instruments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2007 MontaVista Software, Inc., <source@mvista.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * ----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * ----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/ide.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) /* Offset of the primary interface registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define IDE_PALM_ATA_PRI_REG_OFFSET 0x1F0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) /* Primary Control Offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define IDE_PALM_ATA_PRI_CTL_OFFSET 0x3F6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define BK3710_BMICP		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define BK3710_BMISP		0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define BK3710_BMIDTP		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define BK3710_IDETIMP		0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define BK3710_IDESTATUS	0x47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define BK3710_UDMACTL		0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define BK3710_MISCCTL		0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define BK3710_REGSTB		0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define BK3710_REGRCVR		0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define BK3710_DATSTB		0x5C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define BK3710_DATRCVR		0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define BK3710_DMASTB		0x64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define BK3710_DMARCVR		0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define BK3710_UDMASTB		0x6C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define BK3710_UDMATRP		0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define BK3710_UDMAENV		0x74
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define BK3710_IORDYTMP		0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static unsigned ideclk_period; /* in nanoseconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) struct palm_bk3710_udmatiming {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	unsigned int rptime;	/* tRP -- Ready to pause time (nsec) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	unsigned int cycletime;	/* tCYCTYP2/2 -- avg Cycle Time (nsec) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 				/* tENV is always a minimum of 20 nsec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	{ 160, 240 / 2 },	/* UDMA Mode 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	{ 125, 160 / 2 },	/* UDMA Mode 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	{ 100, 120 / 2 },	/* UDMA Mode 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	{ 100,  90 / 2 },	/* UDMA Mode 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	{ 100,  60 / 2 },	/* UDMA Mode 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	{  85,  40 / 2 },	/* UDMA Mode 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 				    unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	u8 tenv, trp, t0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	u32 val32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	u16 val16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	/* DMA Data Setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	t0 = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].cycletime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			  ideclk_period) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	tenv = DIV_ROUND_UP(20, ideclk_period) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	trp = DIV_ROUND_UP(palm_bk3710_udmatimings[mode].rptime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			   ideclk_period) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	/* udmastb Ultra DMA Access Strobe Width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	val32 = readl(base + BK3710_UDMASTB) & (0xFF << (dev ? 0 : 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	val32 |= (t0 << (dev ? 8 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	writel(val32, base + BK3710_UDMASTB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	/* udmatrp Ultra DMA Ready to Pause Time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	val32 = readl(base + BK3710_UDMATRP) & (0xFF << (dev ? 0 : 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	val32 |= (trp << (dev ? 8 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	writel(val32, base + BK3710_UDMATRP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	/* udmaenv Ultra DMA envelop Time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	val32 = readl(base + BK3710_UDMAENV) & (0xFF << (dev ? 0 : 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	val32 |= (tenv << (dev ? 8 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	writel(val32, base + BK3710_UDMAENV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	/* Enable UDMA for Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	val16 = readw(base + BK3710_UDMACTL) | (1 << dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	writew(val16, base + BK3710_UDMACTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) static void palm_bk3710_setdmamode(void __iomem *base, unsigned int dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 				   unsigned short min_cycle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 				   unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	u8 td, tkw, t0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	u32 val32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	u16 val16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	struct ide_timing *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	int cycletime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	t = ide_timing_find_mode(mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	cycletime = max_t(int, t->cycle, min_cycle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	/* DMA Data Setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	t0 = DIV_ROUND_UP(cycletime, ideclk_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	td = DIV_ROUND_UP(t->active, ideclk_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	tkw = t0 - td - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	td -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	val32 = readl(base + BK3710_DMASTB) & (0xFF << (dev ? 0 : 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	val32 |= (td << (dev ? 8 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	writel(val32, base + BK3710_DMASTB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	val32 = readl(base + BK3710_DMARCVR) & (0xFF << (dev ? 0 : 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	val32 |= (tkw << (dev ? 8 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	writel(val32, base + BK3710_DMARCVR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	/* Disable UDMA for Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	val16 = readw(base + BK3710_UDMACTL) & ~(1 << dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	writew(val16, base + BK3710_UDMACTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 				   unsigned int dev, unsigned int cycletime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 				   unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	u8 t2, t2i, t0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	u32 val32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	struct ide_timing *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	t = ide_timing_find_mode(XFER_PIO_0 + mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	/* PIO Data Setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	t0 = DIV_ROUND_UP(cycletime, ideclk_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	t2 = DIV_ROUND_UP(t->active, ideclk_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	t2i = t0 - t2 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	t2 -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	val32 = readl(base + BK3710_DATSTB) & (0xFF << (dev ? 0 : 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	val32 |= (t2 << (dev ? 8 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	writel(val32, base + BK3710_DATSTB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	val32 = readl(base + BK3710_DATRCVR) & (0xFF << (dev ? 0 : 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	val32 |= (t2i << (dev ? 8 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	writel(val32, base + BK3710_DATRCVR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	if (mate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		u8 mode2 = mate->pio_mode - XFER_PIO_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		if (mode2 < mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			mode = mode2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	/* TASKFILE Setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	t0 = DIV_ROUND_UP(t->cyc8b, ideclk_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	t2 = DIV_ROUND_UP(t->act8b, ideclk_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	t2i = t0 - t2 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	t2 -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	val32 = readl(base + BK3710_REGSTB) & (0xFF << (dev ? 0 : 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	val32 |= (t2 << (dev ? 8 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	writel(val32, base + BK3710_REGSTB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	val32 = readl(base + BK3710_REGRCVR) & (0xFF << (dev ? 0 : 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	val32 |= (t2i << (dev ? 8 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	writel(val32, base + BK3710_REGRCVR);
^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) static void palm_bk3710_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	int is_slave = drive->dn & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	void __iomem *base = (void __iomem *)hwif->dma_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	const u8 xferspeed = drive->dma_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	if (xferspeed >= XFER_UDMA_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		palm_bk3710_setudmamode(base, is_slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 					xferspeed - XFER_UDMA_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		palm_bk3710_setdmamode(base, is_slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 				       drive->id[ATA_ID_EIDE_DMA_MIN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 				       xferspeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static void palm_bk3710_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	unsigned int cycle_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	int is_slave = drive->dn & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	ide_drive_t *mate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	void __iomem *base = (void __iomem *)hwif->dma_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	const u8 pio = drive->pio_mode - XFER_PIO_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	 * Obtain the drive PIO data for tuning the Palm Chip registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	cycle_time = ide_pio_cycle_time(drive, pio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	mate = ide_get_pair_dev(drive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	palm_bk3710_setpiomode(base, mate, is_slave, cycle_time, pio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static void palm_bk3710_chipinit(void __iomem *base)
^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) 	 * REVISIT:  the ATA reset signal needs to be managed through a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	 * GPIO, which means it should come from platform_data.  Until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	 * we get and use such information, we have to trust that things
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	 * have been reset before we get here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	 * Program the IDETIMP Register Value based on the following assumptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	 * (ATA_IDETIMP_IDEEN		, ENABLE ) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	 * (ATA_IDETIMP_PREPOST1	, DISABLE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	 * (ATA_IDETIMP_PREPOST0	, DISABLE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	 * DM6446 silicon rev 2.1 and earlier have no observed net benefit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	 * from enabling prefetch/postwrite.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	writew(BIT(15), base + BK3710_IDETIMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	 * UDMACTL Ultra-ATA DMA Control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	 * (ATA_UDMACTL_UDMAP1	, 0 ) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	 * (ATA_UDMACTL_UDMAP0	, 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	writew(0, base + BK3710_UDMACTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	 * MISCCTL Miscellaneous Conrol Register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	 * (ATA_MISCCTL_HWNHLD1P	, 1 cycle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	 * (ATA_MISCCTL_HWNHLD0P	, 1 cycle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	 * (ATA_MISCCTL_TIMORIDE	, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	writel(0x001, base + BK3710_MISCCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	 * IORDYTMP IORDY Timer for Primary Register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	 * (ATA_IORDYTMP_IORDYTMP     , 0xffff  )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	writel(0xFFFF, base + BK3710_IORDYTMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	 * Configure BMISP Register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	 * (ATA_BMISP_DMAEN1	, DISABLE )	|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	 * (ATA_BMISP_DMAEN0	, DISABLE )	|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	 * (ATA_BMISP_IORDYINT	, CLEAR)	|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	 * (ATA_BMISP_INTRSTAT	, CLEAR)	|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	 * (ATA_BMISP_DMAERROR	, CLEAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	writew(0, base + BK3710_BMISP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	palm_bk3710_setpiomode(base, NULL, 0, 600, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	palm_bk3710_setpiomode(base, NULL, 1, 600, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static u8 palm_bk3710_cable_detect(ide_hwif_t *hwif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	return ATA_CBL_PATA80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int palm_bk3710_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	printk(KERN_INFO "    %s: MMIO-DMA\n", hwif->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	if (ide_allocate_dma_engine(hwif))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	hwif->dma_base = hwif->io_ports.data_addr - IDE_PALM_ATA_PRI_REG_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static const struct ide_port_ops palm_bk3710_ports_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	.set_pio_mode		= palm_bk3710_set_pio_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	.set_dma_mode		= palm_bk3710_set_dma_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	.cable_detect		= palm_bk3710_cable_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static struct ide_port_info palm_bk3710_port_info __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	.init_dma		= palm_bk3710_init_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	.port_ops		= &palm_bk3710_ports_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	.dma_ops		= &sff_dma_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	.host_flags		= IDE_HFLAG_MMIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	.pio_mask		= ATA_PIO4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	.mwdma_mask		= ATA_MWDMA2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	.chipset		= ide_palm3710,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static int __init palm_bk3710_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	struct resource *mem, *irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	unsigned long rate, mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	int i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	struct ide_hw hw, *hws[] = { &hw };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	clk = clk_get(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	clk_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	rate = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	if (!rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	/* NOTE:  round *down* to meet minimum timings; we count in clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	ideclk_period = 1000000000UL / rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	if (mem == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		printk(KERN_ERR "failed to get memory region resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	if (irq == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		printk(KERN_ERR "failed to get IRQ resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	mem_size = resource_size(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	if (request_mem_region(mem->start, mem_size, "palm_bk3710") == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		printk(KERN_ERR "failed to request memory region\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	base = ioremap(mem->start, mem_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	if (!base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		printk(KERN_ERR "failed to map IO memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		release_mem_region(mem->start, mem_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	/* Configure the Palm Chip controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	palm_bk3710_chipinit(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	memset(&hw, 0, sizeof(hw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	for (i = 0; i < IDE_NR_PORTS - 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		hw.io_ports_array[i] = (unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 				(base + IDE_PALM_ATA_PRI_REG_OFFSET + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	hw.io_ports.ctl_addr = (unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 			(base + IDE_PALM_ATA_PRI_CTL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	hw.irq = irq->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	hw.dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	palm_bk3710_port_info.udma_mask = rate < 100000000 ? ATA_UDMA4 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 							     ATA_UDMA5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	/* Register the IDE interface with Linux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	rc = ide_host_add(&palm_bk3710_port_info, hws, 1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	return rc;
^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) /* work with hotplug and coldplug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) MODULE_ALIAS("platform:palm_bk3710");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static struct platform_driver platform_bk_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		.name = "palm_bk3710",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static int __init palm_bk3710_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	return platform_driver_probe(&platform_bk_driver, palm_bk3710_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) module_init(palm_bk3710_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) MODULE_LICENSE("GPL");