]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/staging/media/atomisp/platform/intel-mid/intel_mid_pcihelpers.c
media: staging: atomisp: Remove dead code for MID (#1)
[mirror_ubuntu-bionic-kernel.git] / drivers / staging / media / atomisp / platform / intel-mid / intel_mid_pcihelpers.c
1 #include <linux/export.h>
2 #include <linux/pci.h>
3 #include <linux/pm_qos.h>
4 #include <linux/delay.h>
5
6 /* G-Min addition: "platform_is()" lives in intel_mid_pm.h in the MCG
7 * tree, but it's just platform ID info and we don't want to pull in
8 * the whole SFI-based PM architecture.
9 */
10 #define INTEL_ATOM_MRST 0x26
11 #define INTEL_ATOM_MFLD 0x27
12 #define INTEL_ATOM_CLV 0x35
13 #define INTEL_ATOM_MRFLD 0x4a
14 #define INTEL_ATOM_BYT 0x37
15 #define INTEL_ATOM_MOORFLD 0x5a
16 #define INTEL_ATOM_CHT 0x4c
17 static inline int platform_is(u8 model)
18 {
19 return (boot_cpu_data.x86_model == model);
20 }
21
22 #include "../../include/asm/intel_mid_pcihelpers.h"
23
24 /* Unified message bus read/write operation */
25 static DEFINE_SPINLOCK(msgbus_lock);
26
27 static struct pci_dev *pci_root;
28 static struct pm_qos_request pm_qos;
29
30 #define DW_I2C_NEED_QOS (platform_is(INTEL_ATOM_BYT))
31
32 static int intel_mid_msgbus_init(void)
33 {
34 pci_root = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
35 if (!pci_root) {
36 pr_err("%s: Error: msgbus PCI handle NULL\n", __func__);
37 return -ENODEV;
38 }
39
40 if (DW_I2C_NEED_QOS) {
41 pm_qos_add_request(&pm_qos,
42 PM_QOS_CPU_DMA_LATENCY,
43 PM_QOS_DEFAULT_VALUE);
44 }
45 return 0;
46 }
47 fs_initcall(intel_mid_msgbus_init);
48
49 u32 intel_mid_msgbus_read32_raw(u32 cmd)
50 {
51 unsigned long irq_flags;
52 u32 data;
53
54 spin_lock_irqsave(&msgbus_lock, irq_flags);
55 pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_REG, cmd);
56 pci_read_config_dword(pci_root, PCI_ROOT_MSGBUS_DATA_REG, &data);
57 spin_unlock_irqrestore(&msgbus_lock, irq_flags);
58
59 return data;
60 }
61 EXPORT_SYMBOL(intel_mid_msgbus_read32_raw);
62
63 /*
64 * GU: this function is only used by the VISA and 'VXD' drivers.
65 */
66 u32 intel_mid_msgbus_read32_raw_ext(u32 cmd, u32 cmd_ext)
67 {
68 unsigned long irq_flags;
69 u32 data;
70
71 spin_lock_irqsave(&msgbus_lock, irq_flags);
72 pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_EXT_REG, cmd_ext);
73 pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_REG, cmd);
74 pci_read_config_dword(pci_root, PCI_ROOT_MSGBUS_DATA_REG, &data);
75 spin_unlock_irqrestore(&msgbus_lock, irq_flags);
76
77 return data;
78 }
79 EXPORT_SYMBOL(intel_mid_msgbus_read32_raw_ext);
80
81 void intel_mid_msgbus_write32_raw(u32 cmd, u32 data)
82 {
83 unsigned long irq_flags;
84
85 spin_lock_irqsave(&msgbus_lock, irq_flags);
86 pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_DATA_REG, data);
87 pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_REG, cmd);
88 spin_unlock_irqrestore(&msgbus_lock, irq_flags);
89 }
90 EXPORT_SYMBOL(intel_mid_msgbus_write32_raw);
91
92 /*
93 * GU: this function is only used by the VISA and 'VXD' drivers.
94 */
95 void intel_mid_msgbus_write32_raw_ext(u32 cmd, u32 cmd_ext, u32 data)
96 {
97 unsigned long irq_flags;
98
99 spin_lock_irqsave(&msgbus_lock, irq_flags);
100 pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_DATA_REG, data);
101 pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_EXT_REG, cmd_ext);
102 pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_REG, cmd);
103 spin_unlock_irqrestore(&msgbus_lock, irq_flags);
104 }
105 EXPORT_SYMBOL(intel_mid_msgbus_write32_raw_ext);
106
107 u32 intel_mid_msgbus_read32(u8 port, u32 addr)
108 {
109 unsigned long irq_flags;
110 u32 data;
111 u32 cmd;
112 u32 cmdext;
113
114 cmd = (PCI_ROOT_MSGBUS_READ << 24) | (port << 16) |
115 ((addr & 0xff) << 8) | PCI_ROOT_MSGBUS_DWORD_ENABLE;
116 cmdext = addr & 0xffffff00;
117
118 spin_lock_irqsave(&msgbus_lock, irq_flags);
119
120 if (cmdext) {
121 /* This resets to 0 automatically, no need to write 0 */
122 pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_EXT_REG,
123 cmdext);
124 }
125
126 pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_REG, cmd);
127 pci_read_config_dword(pci_root, PCI_ROOT_MSGBUS_DATA_REG, &data);
128 spin_unlock_irqrestore(&msgbus_lock, irq_flags);
129
130 return data;
131 }
132 EXPORT_SYMBOL(intel_mid_msgbus_read32);
133
134 void intel_mid_msgbus_write32(u8 port, u32 addr, u32 data)
135 {
136 unsigned long irq_flags;
137 u32 cmd;
138 u32 cmdext;
139
140 cmd = (PCI_ROOT_MSGBUS_WRITE << 24) | (port << 16) |
141 ((addr & 0xFF) << 8) | PCI_ROOT_MSGBUS_DWORD_ENABLE;
142 cmdext = addr & 0xffffff00;
143
144 spin_lock_irqsave(&msgbus_lock, irq_flags);
145 pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_DATA_REG, data);
146
147 if (cmdext) {
148 /* This resets to 0 automatically, no need to write 0 */
149 pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_EXT_REG,
150 cmdext);
151 }
152
153 pci_write_config_dword(pci_root, PCI_ROOT_MSGBUS_CTRL_REG, cmd);
154 spin_unlock_irqrestore(&msgbus_lock, irq_flags);
155 }
156 EXPORT_SYMBOL(intel_mid_msgbus_write32);
157
158 /* called only from where is later then fs_initcall */
159 u32 intel_mid_soc_stepping(void)
160 {
161 return pci_root->revision;
162 }
163 EXPORT_SYMBOL(intel_mid_soc_stepping);
164
165 static bool is_south_complex_device(struct pci_dev *dev)
166 {
167 unsigned int base_class = dev->class >> 16;
168 unsigned int sub_class = (dev->class & SUB_CLASS_MASK) >> 8;
169
170 /* other than camera, pci bridges and display,
171 * everything else are south complex devices.
172 */
173 if (((base_class == PCI_BASE_CLASS_MULTIMEDIA) &&
174 (sub_class == ISP_SUB_CLASS)) ||
175 (base_class == PCI_BASE_CLASS_BRIDGE) ||
176 ((base_class == PCI_BASE_CLASS_DISPLAY) && !sub_class))
177 return false;
178 else
179 return true;
180 }
181
182 /* In BYT platform, d3_delay for internal south complex devices,
183 * they are not subject to 10 ms d3 to d0 delay required by pci spec.
184 */
185 static void pci_d3_delay_fixup(struct pci_dev *dev)
186 {
187 if (platform_is(INTEL_ATOM_BYT) ||
188 platform_is(INTEL_ATOM_CHT)) {
189 /* All internal devices are in bus 0. */
190 if (dev->bus->number == 0 && is_south_complex_device(dev)) {
191 dev->d3_delay = INTERNAL_PCI_PM_D3_WAIT;
192 dev->d3cold_delay = INTERNAL_PCI_PM_D3_WAIT;
193 }
194 }
195 }
196 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_d3_delay_fixup);