^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) * drivers/mmc/host/via-sdmmc.c - VIA SD/MMC Card Reader driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2008, VIA Technologies Inc. All Rights Reserved.
^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) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mmc/host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define DRV_NAME "via_sdmmc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define PCI_DEVICE_ID_VIA_9530 0x9530
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define VIA_CRDR_SDC_OFF 0x200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define VIA_CRDR_DDMA_OFF 0x400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define VIA_CRDR_PCICTRL_OFF 0x600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define VIA_CRDR_MIN_CLOCK 375000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define VIA_CRDR_MAX_CLOCK 48000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * PCI registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define VIA_CRDR_PCI_WORK_MODE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define VIA_CRDR_PCI_DBG_MODE 0x41
^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) * SDC MMIO Registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define VIA_CRDR_SDCTRL 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define VIA_CRDR_SDCTRL_START 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define VIA_CRDR_SDCTRL_WRITE 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define VIA_CRDR_SDCTRL_SINGLE_WR 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define VIA_CRDR_SDCTRL_SINGLE_RD 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define VIA_CRDR_SDCTRL_MULTI_WR 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define VIA_CRDR_SDCTRL_MULTI_RD 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define VIA_CRDR_SDCTRL_STOP 0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define VIA_CRDR_SDCTRL_RSP_NONE 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define VIA_CRDR_SDCTRL_RSP_R1 0x10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define VIA_CRDR_SDCTRL_RSP_R2 0x20000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define VIA_CRDR_SDCTRL_RSP_R3 0x30000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define VIA_CRDR_SDCTRL_RSP_R1B 0x90000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define VIA_CRDR_SDCARG 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define VIA_CRDR_SDBUSMODE 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define VIA_CRDR_SDMODE_4BIT 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define VIA_CRDR_SDMODE_CLK_ON 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define VIA_CRDR_SDBLKLEN 0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * Bit 0 -Bit 10 : Block length. So, the maximum block length should be 2048.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * Bit 11 - Bit 13 : Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * GPIDET : Select GPI pin to detect card, GPI means CR_CD# in top design.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * INTEN : Enable SD host interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * Bit 16 - Bit 31 : Block count. So, the maximun block count should be 65536.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define VIA_CRDR_SDBLKLEN_GPIDET 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define VIA_CRDR_SDBLKLEN_INTEN 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define VIA_CRDR_MAX_BLOCK_COUNT 65536
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define VIA_CRDR_MAX_BLOCK_LENGTH 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define VIA_CRDR_SDRESP0 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define VIA_CRDR_SDRESP1 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define VIA_CRDR_SDRESP2 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define VIA_CRDR_SDRESP3 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define VIA_CRDR_SDCURBLKCNT 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define VIA_CRDR_SDINTMASK 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * MBDIE : Multiple Blocks transfer Done Interrupt Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * BDDIE : Block Data transfer Done Interrupt Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * CIRIE : Card Insertion or Removal Interrupt Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * CRDIE : Command-Response transfer Done Interrupt Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * CRTOIE : Command-Response response TimeOut Interrupt Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * ASCRDIE : Auto Stop Command-Response transfer Done Interrupt Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * DTIE : Data access Timeout Interrupt Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * SCIE : reSponse CRC error Interrupt Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * RCIE : Read data CRC error Interrupt Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * WCIE : Write data CRC error Interrupt Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define VIA_CRDR_SDINTMASK_MBDIE 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define VIA_CRDR_SDINTMASK_BDDIE 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define VIA_CRDR_SDINTMASK_CIRIE 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define VIA_CRDR_SDINTMASK_CRDIE 0x200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define VIA_CRDR_SDINTMASK_CRTOIE 0x400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define VIA_CRDR_SDINTMASK_ASCRDIE 0x800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define VIA_CRDR_SDINTMASK_DTIE 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define VIA_CRDR_SDINTMASK_SCIE 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define VIA_CRDR_SDINTMASK_RCIE 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define VIA_CRDR_SDINTMASK_WCIE 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define VIA_CRDR_SDACTIVE_INTMASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) (VIA_CRDR_SDINTMASK_MBDIE | VIA_CRDR_SDINTMASK_CIRIE \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) | VIA_CRDR_SDINTMASK_CRDIE | VIA_CRDR_SDINTMASK_CRTOIE \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) | VIA_CRDR_SDINTMASK_DTIE | VIA_CRDR_SDINTMASK_SCIE \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) | VIA_CRDR_SDINTMASK_RCIE | VIA_CRDR_SDINTMASK_WCIE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define VIA_CRDR_SDSTATUS 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * CECC : Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * WP : SD card Write Protect status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * SLOTD : Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * SLOTG : SD SLOT status(Gpi pin status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * MBD : Multiple Blocks transfer Done interrupt status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * BDD : Block Data transfer Done interrupt status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * CD : Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * CIR : Card Insertion or Removal interrupt detected on GPI pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * IO : Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * CRD : Command-Response transfer Done interrupt status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * CRTO : Command-Response response TimeOut interrupt status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * ASCRDIE : Auto Stop Command-Response transfer Done interrupt status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * DT : Data access Timeout interrupt status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * SC : reSponse CRC error interrupt status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * RC : Read data CRC error interrupt status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * WC : Write data CRC error interrupt status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define VIA_CRDR_SDSTS_CECC 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define VIA_CRDR_SDSTS_WP 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define VIA_CRDR_SDSTS_SLOTD 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define VIA_CRDR_SDSTS_SLOTG 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define VIA_CRDR_SDSTS_MBD 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define VIA_CRDR_SDSTS_BDD 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define VIA_CRDR_SDSTS_CD 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define VIA_CRDR_SDSTS_CIR 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define VIA_CRDR_SDSTS_IO 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define VIA_CRDR_SDSTS_CRD 0x200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define VIA_CRDR_SDSTS_CRTO 0x400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define VIA_CRDR_SDSTS_ASCRDIE 0x800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define VIA_CRDR_SDSTS_DT 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define VIA_CRDR_SDSTS_SC 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define VIA_CRDR_SDSTS_RC 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define VIA_CRDR_SDSTS_WC 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define VIA_CRDR_SDSTS_IGN_MASK\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) (VIA_CRDR_SDSTS_BDD | VIA_CRDR_SDSTS_ASCRDIE | VIA_CRDR_SDSTS_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define VIA_CRDR_SDSTS_INT_MASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) (VIA_CRDR_SDSTS_MBD | VIA_CRDR_SDSTS_BDD | VIA_CRDR_SDSTS_CD \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) | VIA_CRDR_SDSTS_CIR | VIA_CRDR_SDSTS_IO | VIA_CRDR_SDSTS_CRD \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) | VIA_CRDR_SDSTS_CRTO | VIA_CRDR_SDSTS_ASCRDIE | VIA_CRDR_SDSTS_DT \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) | VIA_CRDR_SDSTS_SC | VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define VIA_CRDR_SDSTS_W1C_MASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) (VIA_CRDR_SDSTS_CECC | VIA_CRDR_SDSTS_MBD | VIA_CRDR_SDSTS_BDD \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) | VIA_CRDR_SDSTS_CD | VIA_CRDR_SDSTS_CIR | VIA_CRDR_SDSTS_CRD \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) | VIA_CRDR_SDSTS_CRTO | VIA_CRDR_SDSTS_ASCRDIE | VIA_CRDR_SDSTS_DT \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) | VIA_CRDR_SDSTS_SC | VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define VIA_CRDR_SDSTS_CMD_MASK \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) (VIA_CRDR_SDSTS_CRD | VIA_CRDR_SDSTS_CRTO | VIA_CRDR_SDSTS_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define VIA_CRDR_SDSTS_DATA_MASK\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) (VIA_CRDR_SDSTS_MBD | VIA_CRDR_SDSTS_DT \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) | VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define VIA_CRDR_SDSTATUS2 0x2a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * CFE : Enable SD host automatic Clock FReezing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define VIA_CRDR_SDSTS_CFE 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define VIA_CRDR_SDRSPTMO 0x2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define VIA_CRDR_SDCLKSEL 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define VIA_CRDR_SDEXTCTRL 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define VIS_CRDR_SDEXTCTRL_AUTOSTOP_SD 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define VIS_CRDR_SDEXTCTRL_SHIFT_9 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define VIS_CRDR_SDEXTCTRL_MMC_8BIT 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define VIS_CRDR_SDEXTCTRL_RELD_BLK 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define VIS_CRDR_SDEXTCTRL_BAD_CMDA 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define VIS_CRDR_SDEXTCTRL_BAD_DATA 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define VIS_CRDR_SDEXTCTRL_AUTOSTOP_SPI 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define VIA_CRDR_SDEXTCTRL_HISPD 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* 0x38-0xFF reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * Data DMA Control Registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define VIA_CRDR_DMABASEADD 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define VIA_CRDR_DMACOUNTER 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define VIA_CRDR_DMACTRL 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * DIR :Transaction Direction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * 0 : From card to memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * 1 : From memory to card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define VIA_CRDR_DMACTRL_DIR 0x100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define VIA_CRDR_DMACTRL_ENIRQ 0x10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define VIA_CRDR_DMACTRL_SFTRST 0x1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #define VIA_CRDR_DMASTS 0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define VIA_CRDR_DMASTART 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /*0x14-0xFF reserved*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * PCI Control Registers
^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) /*0x0 - 0x1 reserved*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define VIA_CRDR_PCICLKGATT 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * SFTRST :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * 0 : Soft reset all the controller and it will be de-asserted automatically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * 1 : Soft reset is de-asserted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define VIA_CRDR_PCICLKGATT_SFTRST 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * 3V3 : Pad power select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * 0 : 1.8V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * 1 : 3.3V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * NOTE : No mater what the actual value should be, this bit always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * read as 0. This is a hardware bug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define VIA_CRDR_PCICLKGATT_3V3 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * PAD_PWRON : Pad Power on/off select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * 0 : Power off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * 1 : Power on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * NOTE : No mater what the actual value should be, this bit always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * read as 0. This is a hardware bug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #define VIA_CRDR_PCICLKGATT_PAD_PWRON 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) #define VIA_CRDR_PCISDCCLK 0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #define VIA_CRDR_PCIDMACLK 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #define VIA_CRDR_PCIDMACLK_SDC 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #define VIA_CRDR_PCIINTCTRL 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #define VIA_CRDR_PCIINTCTRL_SDCIRQEN 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #define VIA_CRDR_PCIINTSTATUS 0x9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #define VIA_CRDR_PCIINTSTATUS_SDC 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #define VIA_CRDR_PCITMOCTRL 0xa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define VIA_CRDR_PCITMOCTRL_NO 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #define VIA_CRDR_PCITMOCTRL_32US 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define VIA_CRDR_PCITMOCTRL_256US 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) #define VIA_CRDR_PCITMOCTRL_1024US 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #define VIA_CRDR_PCITMOCTRL_256MS 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) #define VIA_CRDR_PCITMOCTRL_512MS 0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #define VIA_CRDR_PCITMOCTRL_1024MS 0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /*0xB-0xFF reserved*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) enum PCI_HOST_CLK_CONTROL {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) PCI_CLK_375K = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) PCI_CLK_8M = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) PCI_CLK_12M = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) PCI_CLK_16M = 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) PCI_CLK_24M = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) PCI_CLK_33M = 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) PCI_CLK_48M = 0x02
^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) struct sdhcreg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) u32 sdcontrol_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u32 sdcmdarg_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) u32 sdbusmode_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) u32 sdblklen_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) u32 sdresp_reg[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) u32 sdcurblkcnt_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) u32 sdintmask_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) u32 sdstatus_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) u32 sdrsptmo_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) u32 sdclksel_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) u32 sdextctrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct pcictrlreg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) u8 reserve[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) u8 pciclkgat_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) u8 pcinfcclk_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) u8 pcimscclk_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) u8 pcisdclk_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) u8 pcicaclk_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) u8 pcidmaclk_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) u8 pciintctrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) u8 pciintstatus_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) u8 pcitmoctrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) u8 Resv;
^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) struct via_crdr_mmc_host {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct mmc_host *mmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct mmc_request *mrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct mmc_command *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct mmc_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) void __iomem *mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) void __iomem *sdhc_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) void __iomem *ddma_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) void __iomem *pcictrl_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) struct pcictrlreg pm_pcictrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct sdhcreg pm_sdhc_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct work_struct carddet_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct tasklet_struct finish_tasklet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct timer_list timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) u8 power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) int reject;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) unsigned int quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* some devices need a very long delay for power to stabilize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) #define VIA_CRDR_QUIRK_300MS_PWRDELAY 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) #define VIA_CMD_TIMEOUT_MS 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static const struct pci_device_id via_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_9530,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {0,}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) MODULE_DEVICE_TABLE(pci, via_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static void via_print_sdchc(struct via_crdr_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) void __iomem *addrbase = host->sdhc_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) pr_debug("SDC MMIO Registers:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) pr_debug("SDCONTROL=%08x, SDCMDARG=%08x, SDBUSMODE=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) readl(addrbase + VIA_CRDR_SDCTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) readl(addrbase + VIA_CRDR_SDCARG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) readl(addrbase + VIA_CRDR_SDBUSMODE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) pr_debug("SDBLKLEN=%08x, SDCURBLKCNT=%08x, SDINTMASK=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) readl(addrbase + VIA_CRDR_SDBLKLEN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) readl(addrbase + VIA_CRDR_SDCURBLKCNT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) readl(addrbase + VIA_CRDR_SDINTMASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) pr_debug("SDSTATUS=%08x, SDCLKSEL=%08x, SDEXTCTRL=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) readl(addrbase + VIA_CRDR_SDSTATUS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) readl(addrbase + VIA_CRDR_SDCLKSEL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) readl(addrbase + VIA_CRDR_SDEXTCTRL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static void via_print_pcictrl(struct via_crdr_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) void __iomem *addrbase = host->pcictrl_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) pr_debug("PCI Control Registers:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) pr_debug("PCICLKGATT=%02x, PCISDCCLK=%02x, PCIDMACLK=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) readb(addrbase + VIA_CRDR_PCICLKGATT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) readb(addrbase + VIA_CRDR_PCISDCCLK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) readb(addrbase + VIA_CRDR_PCIDMACLK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) pr_debug("PCIINTCTRL=%02x, PCIINTSTATUS=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) readb(addrbase + VIA_CRDR_PCIINTCTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) readb(addrbase + VIA_CRDR_PCIINTSTATUS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static void via_save_pcictrlreg(struct via_crdr_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) struct pcictrlreg *pm_pcictrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) void __iomem *addrbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) pm_pcictrl_reg = &(host->pm_pcictrl_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) addrbase = host->pcictrl_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) pm_pcictrl_reg->pciclkgat_reg = readb(addrbase + VIA_CRDR_PCICLKGATT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) pm_pcictrl_reg->pciclkgat_reg |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) VIA_CRDR_PCICLKGATT_3V3 | VIA_CRDR_PCICLKGATT_PAD_PWRON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) pm_pcictrl_reg->pcisdclk_reg = readb(addrbase + VIA_CRDR_PCISDCCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) pm_pcictrl_reg->pcidmaclk_reg = readb(addrbase + VIA_CRDR_PCIDMACLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) pm_pcictrl_reg->pciintctrl_reg = readb(addrbase + VIA_CRDR_PCIINTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) pm_pcictrl_reg->pciintstatus_reg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) readb(addrbase + VIA_CRDR_PCIINTSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) pm_pcictrl_reg->pcitmoctrl_reg = readb(addrbase + VIA_CRDR_PCITMOCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static void via_restore_pcictrlreg(struct via_crdr_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct pcictrlreg *pm_pcictrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) void __iomem *addrbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) pm_pcictrl_reg = &(host->pm_pcictrl_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) addrbase = host->pcictrl_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) writeb(pm_pcictrl_reg->pciclkgat_reg, addrbase + VIA_CRDR_PCICLKGATT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) writeb(pm_pcictrl_reg->pcisdclk_reg, addrbase + VIA_CRDR_PCISDCCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) writeb(pm_pcictrl_reg->pcidmaclk_reg, addrbase + VIA_CRDR_PCIDMACLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) writeb(pm_pcictrl_reg->pciintctrl_reg, addrbase + VIA_CRDR_PCIINTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) writeb(pm_pcictrl_reg->pciintstatus_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) addrbase + VIA_CRDR_PCIINTSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) writeb(pm_pcictrl_reg->pcitmoctrl_reg, addrbase + VIA_CRDR_PCITMOCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static void via_save_sdcreg(struct via_crdr_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct sdhcreg *pm_sdhc_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) void __iomem *addrbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) pm_sdhc_reg = &(host->pm_sdhc_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) addrbase = host->sdhc_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) pm_sdhc_reg->sdcontrol_reg = readl(addrbase + VIA_CRDR_SDCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) pm_sdhc_reg->sdcmdarg_reg = readl(addrbase + VIA_CRDR_SDCARG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) pm_sdhc_reg->sdbusmode_reg = readl(addrbase + VIA_CRDR_SDBUSMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) pm_sdhc_reg->sdblklen_reg = readl(addrbase + VIA_CRDR_SDBLKLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) pm_sdhc_reg->sdcurblkcnt_reg = readl(addrbase + VIA_CRDR_SDCURBLKCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) pm_sdhc_reg->sdintmask_reg = readl(addrbase + VIA_CRDR_SDINTMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) pm_sdhc_reg->sdstatus_reg = readl(addrbase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) pm_sdhc_reg->sdrsptmo_reg = readl(addrbase + VIA_CRDR_SDRSPTMO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) pm_sdhc_reg->sdclksel_reg = readl(addrbase + VIA_CRDR_SDCLKSEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) pm_sdhc_reg->sdextctrl_reg = readl(addrbase + VIA_CRDR_SDEXTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static void via_restore_sdcreg(struct via_crdr_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct sdhcreg *pm_sdhc_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) void __iomem *addrbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) pm_sdhc_reg = &(host->pm_sdhc_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) addrbase = host->sdhc_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) writel(pm_sdhc_reg->sdcontrol_reg, addrbase + VIA_CRDR_SDCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) writel(pm_sdhc_reg->sdcmdarg_reg, addrbase + VIA_CRDR_SDCARG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) writel(pm_sdhc_reg->sdbusmode_reg, addrbase + VIA_CRDR_SDBUSMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) writel(pm_sdhc_reg->sdblklen_reg, addrbase + VIA_CRDR_SDBLKLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) writel(pm_sdhc_reg->sdcurblkcnt_reg, addrbase + VIA_CRDR_SDCURBLKCNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) writel(pm_sdhc_reg->sdintmask_reg, addrbase + VIA_CRDR_SDINTMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) writel(pm_sdhc_reg->sdstatus_reg, addrbase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) writel(pm_sdhc_reg->sdrsptmo_reg, addrbase + VIA_CRDR_SDRSPTMO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) writel(pm_sdhc_reg->sdclksel_reg, addrbase + VIA_CRDR_SDCLKSEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) writel(pm_sdhc_reg->sdextctrl_reg, addrbase + VIA_CRDR_SDEXTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static void via_pwron_sleep(struct via_crdr_mmc_host *sdhost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) if (sdhost->quirks & VIA_CRDR_QUIRK_300MS_PWRDELAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) msleep(300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) msleep(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static void via_set_ddma(struct via_crdr_mmc_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) dma_addr_t dmaaddr, u32 count, int dir, int enirq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) void __iomem *addrbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) u32 ctrl_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (enirq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ctrl_data |= VIA_CRDR_DMACTRL_ENIRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ctrl_data |= VIA_CRDR_DMACTRL_DIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) addrbase = host->ddma_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) writel(dmaaddr, addrbase + VIA_CRDR_DMABASEADD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) writel(count, addrbase + VIA_CRDR_DMACOUNTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) writel(ctrl_data, addrbase + VIA_CRDR_DMACTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) writel(0x01, addrbase + VIA_CRDR_DMASTART);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /* It seems that our DMA can not work normally with 375kHz clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /* FIXME: don't brute-force 8MHz but use PIO at 375kHz !! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) addrbase = host->pcictrl_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (readb(addrbase + VIA_CRDR_PCISDCCLK) == PCI_CLK_375K) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) dev_info(host->mmc->parent, "forcing card speed to 8MHz\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) writeb(PCI_CLK_8M, addrbase + VIA_CRDR_PCISDCCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static void via_sdc_preparedata(struct via_crdr_mmc_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct mmc_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) void __iomem *addrbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) u32 blk_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) WARN_ON(host->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* Sanity checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) BUG_ON(data->blksz > host->mmc->max_blk_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) BUG_ON(data->blocks > host->mmc->max_blk_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) host->data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) count = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ((data->flags & MMC_DATA_READ) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) BUG_ON(count != 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) via_set_ddma(host, sg_dma_address(data->sg), sg_dma_len(data->sg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) (data->flags & MMC_DATA_WRITE) ? 1 : 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) addrbase = host->sdhc_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) blk_reg = data->blksz - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) blk_reg |= VIA_CRDR_SDBLKLEN_GPIDET | VIA_CRDR_SDBLKLEN_INTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) blk_reg |= (data->blocks) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) writel(blk_reg, addrbase + VIA_CRDR_SDBLKLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static void via_sdc_get_response(struct via_crdr_mmc_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct mmc_command *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) void __iomem *addrbase = host->sdhc_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) u32 dwdata0 = readl(addrbase + VIA_CRDR_SDRESP0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) u32 dwdata1 = readl(addrbase + VIA_CRDR_SDRESP1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) u32 dwdata2 = readl(addrbase + VIA_CRDR_SDRESP2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) u32 dwdata3 = readl(addrbase + VIA_CRDR_SDRESP3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (cmd->flags & MMC_RSP_136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) cmd->resp[0] = ((u8) (dwdata1)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) (((u8) (dwdata0 >> 24)) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) (((u8) (dwdata0 >> 16)) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) (((u8) (dwdata0 >> 8)) << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) cmd->resp[1] = ((u8) (dwdata2)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) (((u8) (dwdata1 >> 24)) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) (((u8) (dwdata1 >> 16)) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) (((u8) (dwdata1 >> 8)) << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) cmd->resp[2] = ((u8) (dwdata3)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) (((u8) (dwdata2 >> 24)) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) (((u8) (dwdata2 >> 16)) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) (((u8) (dwdata2 >> 8)) << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) cmd->resp[3] = 0xff |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ((((u8) (dwdata3 >> 24))) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) (((u8) (dwdata3 >> 16)) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) (((u8) (dwdata3 >> 8)) << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) dwdata0 >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) cmd->resp[0] = ((dwdata0 & 0xff) << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) (((dwdata0 >> 8) & 0xff) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) (((dwdata0 >> 16) & 0xff) << 8) | (dwdata1 & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) dwdata1 >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) cmd->resp[1] = ((dwdata1 & 0xff) << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) (((dwdata1 >> 8) & 0xff) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) (((dwdata1 >> 16) & 0xff) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static void via_sdc_send_command(struct via_crdr_mmc_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) struct mmc_command *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) void __iomem *addrbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) struct mmc_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) unsigned int timeout_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) u32 cmdctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) WARN_ON(host->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) data = cmd->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) host->cmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) timeout_ms = cmd->busy_timeout ? cmd->busy_timeout : VIA_CMD_TIMEOUT_MS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) mod_timer(&host->timer, jiffies + msecs_to_jiffies(timeout_ms));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /*Command index*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) cmdctrl = cmd->opcode << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /*Response type*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) switch (mmc_resp_type(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) case MMC_RSP_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) cmdctrl |= VIA_CRDR_SDCTRL_RSP_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) case MMC_RSP_R1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) cmdctrl |= VIA_CRDR_SDCTRL_RSP_R1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) case MMC_RSP_R1B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) cmdctrl |= VIA_CRDR_SDCTRL_RSP_R1B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) case MMC_RSP_R2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) cmdctrl |= VIA_CRDR_SDCTRL_RSP_R2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) case MMC_RSP_R3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) cmdctrl |= VIA_CRDR_SDCTRL_RSP_R3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) pr_err("%s: cmd->flag is not valid\n", mmc_hostname(host->mmc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (!(cmd->data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) goto nodata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) via_sdc_preparedata(host, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /*Command control*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (data->blocks > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (data->flags & MMC_DATA_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) cmdctrl |= VIA_CRDR_SDCTRL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) cmdctrl |= VIA_CRDR_SDCTRL_MULTI_WR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) cmdctrl |= VIA_CRDR_SDCTRL_MULTI_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (data->flags & MMC_DATA_WRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) cmdctrl |= VIA_CRDR_SDCTRL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) cmdctrl |= VIA_CRDR_SDCTRL_SINGLE_WR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) cmdctrl |= VIA_CRDR_SDCTRL_SINGLE_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) nodata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (cmd == host->mrq->stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) cmdctrl |= VIA_CRDR_SDCTRL_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) cmdctrl |= VIA_CRDR_SDCTRL_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) addrbase = host->sdhc_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) writel(cmd->arg, addrbase + VIA_CRDR_SDCARG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) writel(cmdctrl, addrbase + VIA_CRDR_SDCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static void via_sdc_finish_data(struct via_crdr_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct mmc_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) BUG_ON(!host->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) data = host->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) host->data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (data->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) data->bytes_xfered = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) data->bytes_xfered = data->blocks * data->blksz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) ((data->flags & MMC_DATA_READ) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (data->stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) via_sdc_send_command(host, data->stop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) tasklet_schedule(&host->finish_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static void via_sdc_finish_command(struct via_crdr_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) via_sdc_get_response(host, host->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) host->cmd->error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (!host->cmd->data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) tasklet_schedule(&host->finish_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) host->cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static void via_sdc_request(struct mmc_host *mmc, struct mmc_request *mrq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) void __iomem *addrbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct via_crdr_mmc_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) u16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) addrbase = host->pcictrl_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) writeb(VIA_CRDR_PCIDMACLK_SDC, addrbase + VIA_CRDR_PCIDMACLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) status = readw(host->sdhc_mmiobase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) status &= VIA_CRDR_SDSTS_W1C_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) writew(status, host->sdhc_mmiobase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) WARN_ON(host->mrq != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) host->mrq = mrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) status = readw(host->sdhc_mmiobase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (!(status & VIA_CRDR_SDSTS_SLOTG) || host->reject) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) host->mrq->cmd->error = -ENOMEDIUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) tasklet_schedule(&host->finish_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) via_sdc_send_command(host, mrq->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static void via_sdc_set_power(struct via_crdr_mmc_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) unsigned short power, unsigned int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) u8 gatt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) host->power = (1 << power);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) gatt = readb(host->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (host->power == MMC_VDD_165_195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) gatt &= ~VIA_CRDR_PCICLKGATT_3V3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) gatt |= VIA_CRDR_PCICLKGATT_3V3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) gatt |= VIA_CRDR_PCICLKGATT_PAD_PWRON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) gatt &= ~VIA_CRDR_PCICLKGATT_PAD_PWRON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) writeb(gatt, host->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) via_pwron_sleep(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) static void via_sdc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) struct via_crdr_mmc_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) void __iomem *addrbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) u32 org_data, sdextctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) u8 clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) addrbase = host->sdhc_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) org_data = readl(addrbase + VIA_CRDR_SDBUSMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) sdextctrl = readl(addrbase + VIA_CRDR_SDEXTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (ios->bus_width == MMC_BUS_WIDTH_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) org_data &= ~VIA_CRDR_SDMODE_4BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) org_data |= VIA_CRDR_SDMODE_4BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (ios->power_mode == MMC_POWER_OFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) org_data &= ~VIA_CRDR_SDMODE_CLK_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) org_data |= VIA_CRDR_SDMODE_CLK_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (ios->timing == MMC_TIMING_SD_HS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) sdextctrl |= VIA_CRDR_SDEXTCTRL_HISPD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) sdextctrl &= ~VIA_CRDR_SDEXTCTRL_HISPD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) writel(org_data, addrbase + VIA_CRDR_SDBUSMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) writel(sdextctrl, addrbase + VIA_CRDR_SDEXTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (ios->clock >= 48000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) clock = PCI_CLK_48M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) else if (ios->clock >= 33000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) clock = PCI_CLK_33M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) else if (ios->clock >= 24000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) clock = PCI_CLK_24M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) else if (ios->clock >= 16000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) clock = PCI_CLK_16M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) else if (ios->clock >= 12000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) clock = PCI_CLK_12M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) else if (ios->clock >= 8000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) clock = PCI_CLK_8M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) clock = PCI_CLK_375K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) addrbase = host->pcictrl_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (readb(addrbase + VIA_CRDR_PCISDCCLK) != clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) writeb(clock, addrbase + VIA_CRDR_PCISDCCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (ios->power_mode != MMC_POWER_OFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) via_sdc_set_power(host, ios->vdd, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) via_sdc_set_power(host, ios->vdd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) static int via_sdc_get_ro(struct mmc_host *mmc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct via_crdr_mmc_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) u16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) host = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) status = readw(host->sdhc_mmiobase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return !(status & VIA_CRDR_SDSTS_WP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) static const struct mmc_host_ops via_sdc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) .request = via_sdc_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) .set_ios = via_sdc_set_ios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) .get_ro = via_sdc_get_ro,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) static void via_reset_pcictrl(struct via_crdr_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) u8 gatt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) via_save_pcictrlreg(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) via_save_sdcreg(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) gatt = VIA_CRDR_PCICLKGATT_PAD_PWRON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (host->power == MMC_VDD_165_195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) gatt &= VIA_CRDR_PCICLKGATT_3V3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) gatt |= VIA_CRDR_PCICLKGATT_3V3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) writeb(gatt, host->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) via_pwron_sleep(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) gatt |= VIA_CRDR_PCICLKGATT_SFTRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) writeb(gatt, host->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) msleep(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) via_restore_pcictrlreg(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) via_restore_sdcreg(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) static void via_sdc_cmd_isr(struct via_crdr_mmc_host *host, u16 intmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) BUG_ON(intmask == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (!host->cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) pr_err("%s: Got command interrupt 0x%x even "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) "though no command operation was in progress.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) mmc_hostname(host->mmc), intmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (intmask & VIA_CRDR_SDSTS_CRTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) host->cmd->error = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) else if (intmask & VIA_CRDR_SDSTS_SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) host->cmd->error = -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (host->cmd->error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) tasklet_schedule(&host->finish_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) else if (intmask & VIA_CRDR_SDSTS_CRD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) via_sdc_finish_command(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static void via_sdc_data_isr(struct via_crdr_mmc_host *host, u16 intmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) BUG_ON(intmask == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (!host->data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (intmask & VIA_CRDR_SDSTS_DT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) host->data->error = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) else if (intmask & (VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) host->data->error = -EILSEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) via_sdc_finish_data(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) static irqreturn_t via_sdc_isr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) struct via_crdr_mmc_host *sdhost = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) void __iomem *addrbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) u8 pci_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) u16 sd_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) irqreturn_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (!sdhost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) spin_lock(&sdhost->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) addrbase = sdhost->pcictrl_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) pci_status = readb(addrbase + VIA_CRDR_PCIINTSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (!(pci_status & VIA_CRDR_PCIINTSTATUS_SDC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) result = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) addrbase = sdhost->sdhc_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) sd_status = readw(addrbase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) sd_status &= VIA_CRDR_SDSTS_INT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) sd_status &= ~VIA_CRDR_SDSTS_IGN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (!sd_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) result = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (sd_status & VIA_CRDR_SDSTS_CIR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) writew(sd_status & VIA_CRDR_SDSTS_CIR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) addrbase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) schedule_work(&sdhost->carddet_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) sd_status &= ~VIA_CRDR_SDSTS_CIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (sd_status & VIA_CRDR_SDSTS_CMD_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) writew(sd_status & VIA_CRDR_SDSTS_CMD_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) addrbase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) via_sdc_cmd_isr(sdhost, sd_status & VIA_CRDR_SDSTS_CMD_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (sd_status & VIA_CRDR_SDSTS_DATA_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) writew(sd_status & VIA_CRDR_SDSTS_DATA_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) addrbase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) via_sdc_data_isr(sdhost, sd_status & VIA_CRDR_SDSTS_DATA_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) sd_status &= ~(VIA_CRDR_SDSTS_CMD_MASK | VIA_CRDR_SDSTS_DATA_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (sd_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) pr_err("%s: Unexpected interrupt 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) mmc_hostname(sdhost->mmc), sd_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) writew(sd_status, addrbase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) result = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) spin_unlock(&sdhost->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static void via_sdc_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) struct via_crdr_mmc_host *sdhost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) sdhost = from_timer(sdhost, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) spin_lock_irqsave(&sdhost->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (sdhost->mrq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) pr_err("%s: Timeout waiting for hardware interrupt."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) "cmd:0x%x\n", mmc_hostname(sdhost->mmc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) sdhost->mrq->cmd->opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (sdhost->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) writel(VIA_CRDR_DMACTRL_SFTRST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) sdhost->ddma_mmiobase + VIA_CRDR_DMACTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) sdhost->data->error = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) via_sdc_finish_data(sdhost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (sdhost->cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) sdhost->cmd->error = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) sdhost->mrq->cmd->error = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) tasklet_schedule(&sdhost->finish_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) spin_unlock_irqrestore(&sdhost->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) static void via_sdc_tasklet_finish(unsigned long param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) struct via_crdr_mmc_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct mmc_request *mrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) host = (struct via_crdr_mmc_host *)param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) del_timer(&host->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) mrq = host->mrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) host->mrq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) host->cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) host->data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) mmc_request_done(host->mmc, mrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static void via_sdc_card_detect(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) struct via_crdr_mmc_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) void __iomem *addrbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) u16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) host = container_of(work, struct via_crdr_mmc_host, carddet_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) addrbase = host->ddma_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) writel(VIA_CRDR_DMACTRL_SFTRST, addrbase + VIA_CRDR_DMACTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) addrbase = host->pcictrl_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) writeb(VIA_CRDR_PCIDMACLK_SDC, addrbase + VIA_CRDR_PCIDMACLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) addrbase = host->sdhc_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) status = readw(addrbase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (!(status & VIA_CRDR_SDSTS_SLOTG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (host->mrq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) pr_err("%s: Card removed during transfer!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) mmc_hostname(host->mmc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) host->mrq->cmd->error = -ENOMEDIUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) tasklet_schedule(&host->finish_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) via_reset_pcictrl(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) via_print_pcictrl(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) via_print_sdchc(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) mmc_detect_change(host->mmc, msecs_to_jiffies(500));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static void via_init_mmc_host(struct via_crdr_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) struct mmc_host *mmc = host->mmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) void __iomem *addrbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) u32 lenreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) timer_setup(&host->timer, via_sdc_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) spin_lock_init(&host->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) mmc->f_min = VIA_CRDR_MIN_CLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) mmc->f_max = VIA_CRDR_MAX_CLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) mmc->ops = &via_sdc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) /*Hardware cannot do scatter lists*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) mmc->max_segs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) mmc->max_blk_size = VIA_CRDR_MAX_BLOCK_LENGTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) mmc->max_blk_count = VIA_CRDR_MAX_BLOCK_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) mmc->max_seg_size = mmc->max_blk_size * mmc->max_blk_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) mmc->max_req_size = mmc->max_seg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) INIT_WORK(&host->carddet_work, via_sdc_card_detect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) tasklet_init(&host->finish_tasklet, via_sdc_tasklet_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) (unsigned long)host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) addrbase = host->sdhc_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) writel(0x0, addrbase + VIA_CRDR_SDINTMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) lenreg = VIA_CRDR_SDBLKLEN_GPIDET | VIA_CRDR_SDBLKLEN_INTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) writel(lenreg, addrbase + VIA_CRDR_SDBLKLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) status = readw(addrbase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) status &= VIA_CRDR_SDSTS_W1C_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) writew(status, addrbase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) status = readw(addrbase + VIA_CRDR_SDSTATUS2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) status |= VIA_CRDR_SDSTS_CFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) writew(status, addrbase + VIA_CRDR_SDSTATUS2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) writeb(0x0, addrbase + VIA_CRDR_SDEXTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) writel(VIA_CRDR_SDACTIVE_INTMASK, addrbase + VIA_CRDR_SDINTMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) static int via_sd_probe(struct pci_dev *pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) struct mmc_host *mmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) struct via_crdr_mmc_host *sdhost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) u32 base, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) u8 gatt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) pr_info(DRV_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) ": VIA SDMMC controller found at %s [%04x:%04x] (rev %x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) (int)pcidev->revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) ret = pci_enable_device(pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) ret = pci_request_regions(pcidev, DRV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) goto disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) pci_write_config_byte(pcidev, VIA_CRDR_PCI_WORK_MODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) pci_write_config_byte(pcidev, VIA_CRDR_PCI_DBG_MODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) mmc = mmc_alloc_host(sizeof(struct via_crdr_mmc_host), &pcidev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (!mmc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) sdhost = mmc_priv(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) sdhost->mmc = mmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) dev_set_drvdata(&pcidev->dev, sdhost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) len = pci_resource_len(pcidev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) base = pci_resource_start(pcidev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) sdhost->mmiobase = ioremap(base, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (!sdhost->mmiobase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) goto free_mmc_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) sdhost->sdhc_mmiobase =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) sdhost->mmiobase + VIA_CRDR_SDC_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) sdhost->ddma_mmiobase =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) sdhost->mmiobase + VIA_CRDR_DDMA_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) sdhost->pcictrl_mmiobase =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) sdhost->mmiobase + VIA_CRDR_PCICTRL_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) sdhost->power = MMC_VDD_165_195;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) gatt = VIA_CRDR_PCICLKGATT_3V3 | VIA_CRDR_PCICLKGATT_PAD_PWRON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) writeb(gatt, sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) via_pwron_sleep(sdhost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) gatt |= VIA_CRDR_PCICLKGATT_SFTRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) writeb(gatt, sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) msleep(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) via_init_mmc_host(sdhost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) request_irq(pcidev->irq, via_sdc_isr, IRQF_SHARED, DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) sdhost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) goto unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) writeb(VIA_CRDR_PCIINTCTRL_SDCIRQEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) writeb(VIA_CRDR_PCITMOCTRL_1024MS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) sdhost->pcictrl_mmiobase + VIA_CRDR_PCITMOCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) /* device-specific quirks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (pcidev->subsystem_vendor == PCI_VENDOR_ID_LENOVO &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) pcidev->subsystem_device == 0x3891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) sdhost->quirks = VIA_CRDR_QUIRK_300MS_PWRDELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) mmc_add_host(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) iounmap(sdhost->mmiobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) free_mmc_host:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) dev_set_drvdata(&pcidev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) mmc_free_host(mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) pci_release_regions(pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) pci_disable_device(pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) static void via_sd_remove(struct pci_dev *pcidev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) struct via_crdr_mmc_host *sdhost = pci_get_drvdata(pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) u8 gatt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) spin_lock_irqsave(&sdhost->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) /* Ensure we don't accept more commands from mmc layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) sdhost->reject = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /* Disable generating further interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) writeb(0x0, sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (sdhost->mrq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) pr_err("%s: Controller removed during "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) "transfer\n", mmc_hostname(sdhost->mmc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) /* make sure all DMA is stopped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) writel(VIA_CRDR_DMACTRL_SFTRST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) sdhost->ddma_mmiobase + VIA_CRDR_DMACTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) sdhost->mrq->cmd->error = -ENOMEDIUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) if (sdhost->mrq->stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) sdhost->mrq->stop->error = -ENOMEDIUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) tasklet_schedule(&sdhost->finish_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) spin_unlock_irqrestore(&sdhost->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) mmc_remove_host(sdhost->mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) free_irq(pcidev->irq, sdhost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) del_timer_sync(&sdhost->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) tasklet_kill(&sdhost->finish_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) /* switch off power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) gatt = readb(sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) gatt &= ~VIA_CRDR_PCICLKGATT_PAD_PWRON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) writeb(gatt, sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) iounmap(sdhost->mmiobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) dev_set_drvdata(&pcidev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) mmc_free_host(sdhost->mmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) pci_release_regions(pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) pci_disable_device(pcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) pr_info(DRV_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) ": VIA SDMMC controller at %s [%04x:%04x] has been removed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) static void __maybe_unused via_init_sdc_pm(struct via_crdr_mmc_host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) struct sdhcreg *pm_sdhcreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) void __iomem *addrbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) u32 lenreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) u16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) pm_sdhcreg = &(host->pm_sdhc_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) addrbase = host->sdhc_mmiobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) writel(0x0, addrbase + VIA_CRDR_SDINTMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) lenreg = VIA_CRDR_SDBLKLEN_GPIDET | VIA_CRDR_SDBLKLEN_INTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) writel(lenreg, addrbase + VIA_CRDR_SDBLKLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) status = readw(addrbase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) status &= VIA_CRDR_SDSTS_W1C_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) writew(status, addrbase + VIA_CRDR_SDSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) status = readw(addrbase + VIA_CRDR_SDSTATUS2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) status |= VIA_CRDR_SDSTS_CFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) writew(status, addrbase + VIA_CRDR_SDSTATUS2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) writel(pm_sdhcreg->sdcontrol_reg, addrbase + VIA_CRDR_SDCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) writel(pm_sdhcreg->sdcmdarg_reg, addrbase + VIA_CRDR_SDCARG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) writel(pm_sdhcreg->sdintmask_reg, addrbase + VIA_CRDR_SDINTMASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) writel(pm_sdhcreg->sdrsptmo_reg, addrbase + VIA_CRDR_SDRSPTMO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) writel(pm_sdhcreg->sdclksel_reg, addrbase + VIA_CRDR_SDCLKSEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) writel(pm_sdhcreg->sdextctrl_reg, addrbase + VIA_CRDR_SDEXTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) via_print_pcictrl(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) via_print_sdchc(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) static int __maybe_unused via_sd_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) struct via_crdr_mmc_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) host = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) spin_lock_irqsave(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) via_save_pcictrlreg(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) via_save_sdcreg(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) spin_unlock_irqrestore(&host->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) device_wakeup_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) static int __maybe_unused via_sd_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) struct via_crdr_mmc_host *sdhost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) u8 gatt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) sdhost = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) gatt = VIA_CRDR_PCICLKGATT_PAD_PWRON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (sdhost->power == MMC_VDD_165_195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) gatt &= ~VIA_CRDR_PCICLKGATT_3V3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) gatt |= VIA_CRDR_PCICLKGATT_3V3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) writeb(gatt, sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) via_pwron_sleep(sdhost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) gatt |= VIA_CRDR_PCICLKGATT_SFTRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) writeb(gatt, sdhost->pcictrl_mmiobase + VIA_CRDR_PCICLKGATT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) msleep(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) via_restore_pcictrlreg(sdhost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) via_init_sdc_pm(sdhost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) static SIMPLE_DEV_PM_OPS(via_sd_pm_ops, via_sd_suspend, via_sd_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) static struct pci_driver via_sd_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) .id_table = via_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) .probe = via_sd_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) .remove = via_sd_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) .driver.pm = &via_sd_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) module_pci_driver(via_sd_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) MODULE_AUTHOR("VIA Technologies Inc.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) MODULE_DESCRIPTION("VIA SD/MMC Card Interface driver");