Linux Audio

Check our new training course

Loading...
v3.5.6
  1/*
  2 * Copyright (C) 1995,2001 Compaq Computer Corporation
  3 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
  4 * Copyright (C) 2001 IBM Corp.
  5 * Copyright (C) 2003-2004 Intel Corporation
  6 * (c) Copyright 2009 Hewlett-Packard Development Company, L.P.
  7 *
  8 * All rights reserved.
  9 *
 10 * This program is free software; you can redistribute it and/or modify
 11 * it under the terms of the GNU General Public License as published by
 12 * the Free Software Foundation; either version 2 of the License, or (at
 13 * your option) any later version.
 14 *
 15 * This program is distributed in the hope that it will be useful, but
 16 * WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 18 * NON INFRINGEMENT.  See the GNU General Public License for more
 19 * details.
 20 *
 21 * You should have received a copy of the GNU General Public License
 22 * along with this program; if not, write to the Free Software
 23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 24 */
 25
 26#include <linux/pci.h>
 27#include <linux/export.h>
 28#include <linux/pci_hotplug.h>
 29
 30static struct hpp_type0 pci_default_type0 = {
 31	.revision = 1,
 32	.cache_line_size = 8,
 33	.latency_timer = 0x40,
 34	.enable_serr = 0,
 35	.enable_perr = 0,
 36};
 37
 38static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp)
 39{
 40	u16 pci_cmd, pci_bctl;
 41
 42	if (!hpp) {
 43		/*
 44		 * Perhaps we *should* use default settings for PCIe, but
 45		 * pciehp didn't, so we won't either.
 46		 */
 47		if (pci_is_pcie(dev))
 48			return;
 49		dev_info(&dev->dev, "using default PCI settings\n");
 50		hpp = &pci_default_type0;
 51	}
 52
 53	if (hpp->revision > 1) {
 54		dev_warn(&dev->dev,
 55			 "PCI settings rev %d not supported; using defaults\n",
 56			 hpp->revision);
 57		hpp = &pci_default_type0;
 58	}
 59
 60	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size);
 61	pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer);
 62	pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
 63	if (hpp->enable_serr)
 64		pci_cmd |= PCI_COMMAND_SERR;
 65	else
 66		pci_cmd &= ~PCI_COMMAND_SERR;
 67	if (hpp->enable_perr)
 68		pci_cmd |= PCI_COMMAND_PARITY;
 69	else
 70		pci_cmd &= ~PCI_COMMAND_PARITY;
 71	pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
 72
 73	/* Program bridge control value */
 74	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
 75		pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
 76				      hpp->latency_timer);
 77		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
 78		if (hpp->enable_serr)
 79			pci_bctl |= PCI_BRIDGE_CTL_SERR;
 80		else
 81			pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
 82		if (hpp->enable_perr)
 83			pci_bctl |= PCI_BRIDGE_CTL_PARITY;
 84		else
 85			pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
 86		pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
 87	}
 88}
 89
 90static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp)
 91{
 92	if (hpp)
 93		dev_warn(&dev->dev, "PCI-X settings not supported\n");
 94}
 95
 96static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
 97{
 98	int pos;
 99	u16 reg16;
100	u32 reg32;
101
102	if (!hpp)
103		return;
104
105	/* Find PCI Express capability */
106	pos = pci_pcie_cap(dev);
107	if (!pos)
108		return;
109
110	if (hpp->revision > 1) {
111		dev_warn(&dev->dev, "PCIe settings rev %d not supported\n",
112			 hpp->revision);
113		return;
114	}
115
116	/* Initialize Device Control Register */
117	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
118	reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or;
119	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
120
121	/* Initialize Link Control Register */
122	if (dev->subordinate) {
123		pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &reg16);
124		reg16 = (reg16 & hpp->pci_exp_lnkctl_and)
125			| hpp->pci_exp_lnkctl_or;
126		pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16);
127	}
128
129	/* Find Advanced Error Reporting Enhanced Capability */
130	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
131	if (!pos)
132		return;
133
134	/* Initialize Uncorrectable Error Mask Register */
135	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &reg32);
136	reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or;
137	pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32);
138
139	/* Initialize Uncorrectable Error Severity Register */
140	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &reg32);
141	reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or;
142	pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32);
143
144	/* Initialize Correctable Error Mask Register */
145	pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg32);
146	reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or;
147	pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32);
148
149	/* Initialize Advanced Error Capabilities and Control Register */
150	pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
151	reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or;
152	pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
153
154	/*
155	 * FIXME: The following two registers are not supported yet.
156	 *
157	 *   o Secondary Uncorrectable Error Severity Register
158	 *   o Secondary Uncorrectable Error Mask Register
159	 */
160}
161
162void pci_configure_slot(struct pci_dev *dev)
163{
164	struct pci_dev *cdev;
165	struct hotplug_params hpp;
166	int ret;
167
168	if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
169			(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
170			(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
171		return;
172
173	if (dev->bus && dev->bus->self)
174		pcie_bus_configure_settings(dev->bus,
175					    dev->bus->self->pcie_mpss);
176
177	memset(&hpp, 0, sizeof(hpp));
178	ret = pci_get_hp_params(dev, &hpp);
179	if (ret)
180		dev_warn(&dev->dev, "no hotplug settings from platform\n");
181
182	program_hpp_type2(dev, hpp.t2);
183	program_hpp_type1(dev, hpp.t1);
184	program_hpp_type0(dev, hpp.t0);
185
186	if (dev->subordinate) {
187		list_for_each_entry(cdev, &dev->subordinate->devices,
188				    bus_list)
189			pci_configure_slot(cdev);
190	}
191}
192EXPORT_SYMBOL_GPL(pci_configure_slot);
v3.15
  1/*
  2 * Copyright (C) 1995,2001 Compaq Computer Corporation
  3 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
  4 * Copyright (C) 2001 IBM Corp.
  5 * Copyright (C) 2003-2004 Intel Corporation
  6 * (c) Copyright 2009 Hewlett-Packard Development Company, L.P.
  7 *
  8 * All rights reserved.
  9 *
 10 * This program is free software; you can redistribute it and/or modify
 11 * it under the terms of the GNU General Public License as published by
 12 * the Free Software Foundation; either version 2 of the License, or (at
 13 * your option) any later version.
 14 *
 15 * This program is distributed in the hope that it will be useful, but
 16 * WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 18 * NON INFRINGEMENT.  See the GNU General Public License for more
 19 * details.
 20 *
 21 * You should have received a copy of the GNU General Public License
 22 * along with this program; if not, write to the Free Software
 23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 24 */
 25
 26#include <linux/pci.h>
 27#include <linux/export.h>
 28#include <linux/pci_hotplug.h>
 29
 30static struct hpp_type0 pci_default_type0 = {
 31	.revision = 1,
 32	.cache_line_size = 8,
 33	.latency_timer = 0x40,
 34	.enable_serr = 0,
 35	.enable_perr = 0,
 36};
 37
 38static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp)
 39{
 40	u16 pci_cmd, pci_bctl;
 41
 42	if (!hpp) {
 43		/*
 44		 * Perhaps we *should* use default settings for PCIe, but
 45		 * pciehp didn't, so we won't either.
 46		 */
 47		if (pci_is_pcie(dev))
 48			return;
 49		dev_info(&dev->dev, "using default PCI settings\n");
 50		hpp = &pci_default_type0;
 51	}
 52
 53	if (hpp->revision > 1) {
 54		dev_warn(&dev->dev,
 55			 "PCI settings rev %d not supported; using defaults\n",
 56			 hpp->revision);
 57		hpp = &pci_default_type0;
 58	}
 59
 60	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size);
 61	pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer);
 62	pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
 63	if (hpp->enable_serr)
 64		pci_cmd |= PCI_COMMAND_SERR;
 65	else
 66		pci_cmd &= ~PCI_COMMAND_SERR;
 67	if (hpp->enable_perr)
 68		pci_cmd |= PCI_COMMAND_PARITY;
 69	else
 70		pci_cmd &= ~PCI_COMMAND_PARITY;
 71	pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
 72
 73	/* Program bridge control value */
 74	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
 75		pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
 76				      hpp->latency_timer);
 77		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
 78		if (hpp->enable_serr)
 79			pci_bctl |= PCI_BRIDGE_CTL_SERR;
 80		else
 81			pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
 82		if (hpp->enable_perr)
 83			pci_bctl |= PCI_BRIDGE_CTL_PARITY;
 84		else
 85			pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
 86		pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
 87	}
 88}
 89
 90static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp)
 91{
 92	if (hpp)
 93		dev_warn(&dev->dev, "PCI-X settings not supported\n");
 94}
 95
 96static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
 97{
 98	int pos;
 
 99	u32 reg32;
100
101	if (!hpp)
102		return;
103
 
 
 
 
 
104	if (hpp->revision > 1) {
105		dev_warn(&dev->dev, "PCIe settings rev %d not supported\n",
106			 hpp->revision);
107		return;
108	}
109
110	/* Initialize Device Control Register */
111	pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
112			~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or);
 
113
114	/* Initialize Link Control Register */
115	if (dev->subordinate)
116		pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
117			~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or);
 
 
 
118
119	/* Find Advanced Error Reporting Enhanced Capability */
120	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
121	if (!pos)
122		return;
123
124	/* Initialize Uncorrectable Error Mask Register */
125	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &reg32);
126	reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or;
127	pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32);
128
129	/* Initialize Uncorrectable Error Severity Register */
130	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &reg32);
131	reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or;
132	pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32);
133
134	/* Initialize Correctable Error Mask Register */
135	pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg32);
136	reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or;
137	pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32);
138
139	/* Initialize Advanced Error Capabilities and Control Register */
140	pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
141	reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or;
142	pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
143
144	/*
145	 * FIXME: The following two registers are not supported yet.
146	 *
147	 *   o Secondary Uncorrectable Error Severity Register
148	 *   o Secondary Uncorrectable Error Mask Register
149	 */
150}
151
152void pci_configure_slot(struct pci_dev *dev)
153{
154	struct pci_dev *cdev;
155	struct hotplug_params hpp;
156	int ret;
157
158	if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
159			(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
160			(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
161		return;
162
163	if (dev->bus)
164		pcie_bus_configure_settings(dev->bus);
 
165
166	memset(&hpp, 0, sizeof(hpp));
167	ret = pci_get_hp_params(dev, &hpp);
168	if (ret)
169		dev_warn(&dev->dev, "no hotplug settings from platform\n");
170
171	program_hpp_type2(dev, hpp.t2);
172	program_hpp_type1(dev, hpp.t1);
173	program_hpp_type0(dev, hpp.t0);
174
175	if (dev->subordinate) {
176		list_for_each_entry(cdev, &dev->subordinate->devices,
177				    bus_list)
178			pci_configure_slot(cdev);
179	}
180}
181EXPORT_SYMBOL_GPL(pci_configure_slot);