linux/arch/mips/loongson/common/cs5536/cs5536_ide.c
<<
>>
Prefs
   1/*
   2 * the IDE Virtual Support Module of AMD CS5536
   3 *
   4 * Copyright (C) 2007 Lemote, Inc.
   5 * Author : jlliu, liujl@lemote.com
   6 *
   7 * Copyright (C) 2009 Lemote, Inc.
   8 * Author: Wu Zhangjin, wuzhangjin@gmail.com
   9 *
  10 * This program is free software; you can redistribute  it and/or modify it
  11 * under  the terms of  the GNU General  Public License as published by the
  12 * Free Software Foundation;  either version 2 of the  License, or (at your
  13 * option) any later version.
  14 */
  15
  16#include <cs5536/cs5536.h>
  17#include <cs5536/cs5536_pci.h>
  18
  19void pci_ide_write_reg(int reg, u32 value)
  20{
  21        u32 hi = 0, lo = value;
  22
  23        switch (reg) {
  24        case PCI_COMMAND:
  25                _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
  26                if (value & PCI_COMMAND_MASTER)
  27                        lo |= (0x03 << 4);
  28                else
  29                        lo &= ~(0x03 << 4);
  30                _wrmsr(GLIU_MSR_REG(GLIU_PAE), hi, lo);
  31                break;
  32        case PCI_STATUS:
  33                if (value & PCI_STATUS_PARITY) {
  34                        _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
  35                        if (lo & SB_PARE_ERR_FLAG) {
  36                                lo = (lo & 0x0000ffff) | SB_PARE_ERR_FLAG;
  37                                _wrmsr(SB_MSR_REG(SB_ERROR), hi, lo);
  38                        }
  39                }
  40                break;
  41        case PCI_CACHE_LINE_SIZE:
  42                value &= 0x0000ff00;
  43                _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
  44                hi &= 0xffffff00;
  45                hi |= (value >> 8);
  46                _wrmsr(SB_MSR_REG(SB_CTRL), hi, lo);
  47                break;
  48        case PCI_BAR4_REG:
  49                if (value == PCI_BAR_RANGE_MASK) {
  50                        _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
  51                        lo |= SOFT_BAR_IDE_FLAG;
  52                        _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
  53                } else if (value & 0x01) {
  54                        _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
  55                        lo = (value & 0xfffffff0) | 0x1;
  56                        _wrmsr(IDE_MSR_REG(IDE_IO_BAR), hi, lo);
  57
  58                        value &= 0xfffffffc;
  59                        hi = 0x60000000 | ((value & 0x000ff000) >> 12);
  60                        lo = 0x000ffff0 | ((value & 0x00000fff) << 20);
  61                        _wrmsr(GLIU_MSR_REG(GLIU_IOD_BM2), hi, lo);
  62                }
  63                break;
  64        case PCI_IDE_CFG_REG:
  65                if (value == CS5536_IDE_FLASH_SIGNATURE) {
  66                        _rdmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), &hi, &lo);
  67                        lo |= 0x01;
  68                        _wrmsr(DIVIL_MSR_REG(DIVIL_BALL_OPTS), hi, lo);
  69                } else {
  70                        _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
  71                        lo = value;
  72                        _wrmsr(IDE_MSR_REG(IDE_CFG), hi, lo);
  73                }
  74                break;
  75        case PCI_IDE_DTC_REG:
  76                _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
  77                lo = value;
  78                _wrmsr(IDE_MSR_REG(IDE_DTC), hi, lo);
  79                break;
  80        case PCI_IDE_CAST_REG:
  81                _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
  82                lo = value;
  83                _wrmsr(IDE_MSR_REG(IDE_CAST), hi, lo);
  84                break;
  85        case PCI_IDE_ETC_REG:
  86                _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
  87                lo = value;
  88                _wrmsr(IDE_MSR_REG(IDE_ETC), hi, lo);
  89                break;
  90        case PCI_IDE_PM_REG:
  91                _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
  92                lo = value;
  93                _wrmsr(IDE_MSR_REG(IDE_INTERNAL_PM), hi, lo);
  94                break;
  95        default:
  96                break;
  97        }
  98}
  99
 100u32 pci_ide_read_reg(int reg)
 101{
 102        u32 conf_data = 0;
 103        u32 hi, lo;
 104
 105        switch (reg) {
 106        case PCI_VENDOR_ID:
 107                conf_data =
 108                    CFG_PCI_VENDOR_ID(CS5536_IDE_DEVICE_ID, CS5536_VENDOR_ID);
 109                break;
 110        case PCI_COMMAND:
 111                _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
 112                if (lo & 0xfffffff0)
 113                        conf_data |= PCI_COMMAND_IO;
 114                _rdmsr(GLIU_MSR_REG(GLIU_PAE), &hi, &lo);
 115                if ((lo & 0x30) == 0x30)
 116                        conf_data |= PCI_COMMAND_MASTER;
 117                break;
 118        case PCI_STATUS:
 119                conf_data |= PCI_STATUS_66MHZ;
 120                conf_data |= PCI_STATUS_FAST_BACK;
 121                _rdmsr(SB_MSR_REG(SB_ERROR), &hi, &lo);
 122                if (lo & SB_PARE_ERR_FLAG)
 123                        conf_data |= PCI_STATUS_PARITY;
 124                conf_data |= PCI_STATUS_DEVSEL_MEDIUM;
 125                break;
 126        case PCI_CLASS_REVISION:
 127                _rdmsr(IDE_MSR_REG(IDE_CAP), &hi, &lo);
 128                conf_data = lo & 0x000000ff;
 129                conf_data |= (CS5536_IDE_CLASS_CODE << 8);
 130                break;
 131        case PCI_CACHE_LINE_SIZE:
 132                _rdmsr(SB_MSR_REG(SB_CTRL), &hi, &lo);
 133                hi &= 0x000000f8;
 134                conf_data = CFG_PCI_CACHE_LINE_SIZE(PCI_NORMAL_HEADER_TYPE, hi);
 135                break;
 136        case PCI_BAR4_REG:
 137                _rdmsr(GLCP_MSR_REG(GLCP_SOFT_COM), &hi, &lo);
 138                if (lo & SOFT_BAR_IDE_FLAG) {
 139                        conf_data = CS5536_IDE_RANGE |
 140                            PCI_BASE_ADDRESS_SPACE_IO;
 141                        lo &= ~SOFT_BAR_IDE_FLAG;
 142                        _wrmsr(GLCP_MSR_REG(GLCP_SOFT_COM), hi, lo);
 143                } else {
 144                        _rdmsr(IDE_MSR_REG(IDE_IO_BAR), &hi, &lo);
 145                        conf_data = lo & 0xfffffff0;
 146                        conf_data |= 0x01;
 147                        conf_data &= ~0x02;
 148                }
 149                break;
 150        case PCI_CARDBUS_CIS:
 151                conf_data = PCI_CARDBUS_CIS_POINTER;
 152                break;
 153        case PCI_SUBSYSTEM_VENDOR_ID:
 154                conf_data =
 155                    CFG_PCI_VENDOR_ID(CS5536_IDE_SUB_ID, CS5536_SUB_VENDOR_ID);
 156                break;
 157        case PCI_ROM_ADDRESS:
 158                conf_data = PCI_EXPANSION_ROM_BAR;
 159                break;
 160        case PCI_CAPABILITY_LIST:
 161                conf_data = PCI_CAPLIST_POINTER;
 162                break;
 163        case PCI_INTERRUPT_LINE:
 164                conf_data =
 165                    CFG_PCI_INTERRUPT_LINE(PCI_DEFAULT_PIN, CS5536_IDE_INTR);
 166                break;
 167        case PCI_IDE_CFG_REG:
 168                _rdmsr(IDE_MSR_REG(IDE_CFG), &hi, &lo);
 169                conf_data = lo;
 170                break;
 171        case PCI_IDE_DTC_REG:
 172                _rdmsr(IDE_MSR_REG(IDE_DTC), &hi, &lo);
 173                conf_data = lo;
 174                break;
 175        case PCI_IDE_CAST_REG:
 176                _rdmsr(IDE_MSR_REG(IDE_CAST), &hi, &lo);
 177                conf_data = lo;
 178                break;
 179        case PCI_IDE_ETC_REG:
 180                _rdmsr(IDE_MSR_REG(IDE_ETC), &hi, &lo);
 181                conf_data = lo;
 182                break;
 183        case PCI_IDE_PM_REG:
 184                _rdmsr(IDE_MSR_REG(IDE_INTERNAL_PM), &hi, &lo);
 185                conf_data = lo;
 186                break;
 187        default:
 188                break;
 189        }
 190
 191        return conf_data;
 192}
 193