1296077Sadrian/*-
2296077Sadrian * Copyright (c) 2015 Landon Fuller <landon@landonf.org>
3296077Sadrian * All rights reserved.
4296077Sadrian *
5296077Sadrian * Redistribution and use in source and binary forms, with or without
6296077Sadrian * modification, are permitted provided that the following conditions
7296077Sadrian * are met:
8296077Sadrian * 1. Redistributions of source code must retain the above copyright
9296077Sadrian *    notice, this list of conditions and the following disclaimer,
10296077Sadrian *    without modification.
11296077Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12296077Sadrian *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13296077Sadrian *    redistribution must be conditioned upon including a substantially
14296077Sadrian *    similar Disclaimer requirement for further binary redistribution.
15296077Sadrian *
16296077Sadrian * NO WARRANTY
17296077Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18296077Sadrian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19296077Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20296077Sadrian * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21296077Sadrian * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22296077Sadrian * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23296077Sadrian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24296077Sadrian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25296077Sadrian * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26296077Sadrian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27296077Sadrian * THE POSSIBILITY OF SUCH DAMAGES.
28296077Sadrian *
29296077Sadrian * $FreeBSD$
30296077Sadrian */
31296077Sadrian
32296077Sadrian#ifndef _BHND_CORES_PCI_BHND_PCIVAR_H_
33296077Sadrian#define _BHND_CORES_PCI_BHND_PCIVAR_H_
34296077Sadrian
35296077Sadrian#include <sys/param.h>
36296077Sadrian#include <sys/bus.h>
37296077Sadrian
38296077Sadrian/*
39296077Sadrian * Shared PCI Bridge/PCI Host Bridge definitions.
40296077Sadrian */
41296077Sadrian
42298479SadrianDECLARE_CLASS(bhnd_pci_driver);
43298479Sadrianstruct bhnd_pci_softc;
44296077Sadrian
45298479Sadrianint		bhnd_pci_generic_probe(device_t dev);
46298479Sadrianint		bhnd_pci_generic_attach(device_t dev);
47298479Sadrianint		bhnd_pci_generic_detach(device_t dev);
48298479Sadrianint		bhnd_pci_generic_suspend(device_t dev);
49298479Sadrianint		bhnd_pci_generic_resume(device_t dev);
50298479Sadrian
51298479Sadrianuint32_t	bhnd_pcie_read_proto_reg(struct bhnd_pci_softc *sc,
52298479Sadrian		    uint32_t addr);
53298479Sadrianvoid		bhnd_pcie_write_proto_reg(struct bhnd_pci_softc *sc,
54298479Sadrian		    uint32_t addr, uint32_t val);
55298479Sadrianint		bhnd_pcie_mdio_read(struct bhnd_pci_softc *sc, int phy,
56298479Sadrian		    int reg);
57298479Sadrianint		bhnd_pcie_mdio_write(struct bhnd_pci_softc *sc, int phy,
58298479Sadrian		    int reg, int val);
59298479Sadrianint		bhnd_pcie_mdio_read_ext(struct bhnd_pci_softc *sc, int phy,
60298479Sadrian		    int devaddr, int reg);
61298479Sadrianint		bhnd_pcie_mdio_write_ext(struct bhnd_pci_softc *sc, int phy,
62298479Sadrian		    int devaddr, int reg, int val);
63298479Sadrian
64298479Sadrian/** PCI register block layouts. */
65296077Sadriantypedef enum {
66296077Sadrian	BHND_PCI_REGFMT_PCI	= 0,	/* PCI register definitions */
67296077Sadrian	BHND_PCI_REGFMT_PCIE	= 1,	/* PCIe-Gen1 register definitions */
68296077Sadrian} bhnd_pci_regfmt_t;
69296077Sadrian
70298479Sadrian/** PCI (base driver) quirks */
71298479Sadrianenum {
72298479Sadrian	/**
73298479Sadrian	 * The PCIe SerDes requires use of a non-standard Clause 22
74298479Sadrian	 * address extension mechanism to access extended MDIO registers.
75298479Sadrian	 */
76298479Sadrian	BHND_PCI_QUIRK_SD_C22_EXTADDR          = (1<<0),
77298479Sadrian};
78298479Sadrian
79298479Sadrian/**
80298479Sadrian * bhnd_pci child device info
81298479Sadrian */
82298479Sadrianstruct bhnd_pci_devinfo {
83298479Sadrian	struct resource_list	resources;
84298479Sadrian};
85298479Sadrian
86298479Sadrian/*
87298479Sadrian * Generic PCI bridge/end-point driver state.
88298479Sadrian *
89298479Sadrian * Must be first member of all subclass softc structures.
90298479Sadrian */
91298479Sadrianstruct bhnd_pci_softc {
92298479Sadrian	device_t		 dev;		/**< pci device */
93298479Sadrian	uint32_t		 quirks;	/**< quirk flags */
94298479Sadrian	bhnd_pci_regfmt_t	 regfmt;	/**< register format */
95298479Sadrian
96298479Sadrian	struct mtx		 mtx;		/**< state mutex used to protect
97298479Sadrian						     interdependent register
98298479Sadrian						     accesses. */
99298479Sadrian
100298479Sadrian	struct bhnd_resource	*mem_res;	/**< device register block. */
101298479Sadrian	int			 mem_rid;	/**< register block RID */
102298479Sadrian};
103298479Sadrian
104298479Sadrian
105298479Sadrian#define	BHND_PCI_LOCK_INIT(sc) \
106298479Sadrian	mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \
107298479Sadrian	    "BHND PCI driver lock", MTX_DEF)
108298479Sadrian#define	BHND_PCI_LOCK(sc)			mtx_lock(&(sc)->mtx)
109298479Sadrian#define	BHND_PCI_UNLOCK(sc)			mtx_unlock(&(sc)->mtx)
110298479Sadrian#define	BHND_PCI_LOCK_ASSERT(sc, what)	mtx_assert(&(sc)->mtx, what)
111298479Sadrian#define	BHND_PCI_LOCK_DESTROY(sc)		mtx_destroy(&(sc)->mtx)
112298479Sadrian
113298479Sadrian/* BHND_PCI_*_REG_(GET|SET) implementation */
114298479Sadrian#define	_BHND_PCI_REG_GET(_regval, _mask, _shift)		\
115296077Sadrian	((_regval & _mask) >> _shift)
116298479Sadrian#define _BHND_PCI_REG_SET(_regval, _mask, _shift, _setval)	\
117296077Sadrian	(((_regval) & ~ _mask) | (((_setval) << _shift) & _mask))
118296077Sadrian
119296077Sadrian/**
120296077Sadrian * Extract a register value by applying _MASK and _SHIFT defines.
121296077Sadrian *
122296077Sadrian * @param _regv The register value containing the desired attribute
123296077Sadrian * @param _attr The register attribute name to which to append `_MASK`/`_SHIFT`
124296077Sadrian * suffixes.
125296077Sadrian */
126298479Sadrian#define	BHND_PCI_REG_GET(_regv, _attr)	\
127298479Sadrian	_BHND_PCI_REG_GET(_regv, _attr ## _MASK, _attr ## _SHIFT)
128296077Sadrian
129296077Sadrian/**
130296077Sadrian * Insert a value in @p _regv by applying _MASK and _SHIFT defines.
131296077Sadrian *
132296077Sadrian * @param _regv The current register value.
133296077Sadrian * @param _attr The register attribute name to which to append `_MASK`/`_SHIFT`
134296077Sadrian * suffixes.
135296077Sadrian * @param _val The value to be set in @p _regv.
136296077Sadrian */
137298479Sadrian#define	BHND_PCI_REG_SET(_regv, _attr, _val)		\
138298479Sadrian	_BHND_PCI_REG_SET(_regv, _attr ## _MASK, _attr ## _SHIFT, _val)
139296077Sadrian
140296077Sadrian/**
141296077Sadrian * Extract a value by applying _MASK and _SHIFT defines to the common
142296077Sadrian * PCI/PCIe register definition @p _regv
143296077Sadrian *
144298479Sadrian * @param _regf The PCI core register format (BHND_PCI_REGFMT_*).
145296077Sadrian * @param _regv The register value containing the desired attribute
146296077Sadrian * @param _attr The register attribute name to which to prepend the register
147296077Sadrian * definition prefix and append `_MASK`/`_SHIFT` suffixes.
148296077Sadrian */
149298479Sadrian#define BHND_PCI_CMN_REG_GET(_regf, _regv, _attr)		\
150298479Sadrian	_BHND_PCI_REG_GET(_regv,				\
151296077Sadrian	    BHND_PCI_COMMON_REG((_regf), _attr ## _MASK),	\
152296077Sadrian	    BHND_PCI_COMMON_REG((_regf), _attr ## _SHIFT))
153296077Sadrian
154296077Sadrian/**
155296077Sadrian * Insert a register value by applying _MASK and _SHIFT defines to the common
156296077Sadrian * PCI/PCIe register definition @p _regv
157296077Sadrian *
158298479Sadrian * @param _regf The PCI core register format (BHND_PCI_REGFMT_*).
159296077Sadrian * @param _regv The register value containing the desired attribute
160296077Sadrian * @param _attr The register attribute name to which to prepend the register
161296077Sadrian * definition prefix and append `_MASK`/`_SHIFT` suffixes.
162296077Sadrian * @param _val The value to bet set in @p _regv.
163296077Sadrian */
164298479Sadrian#define BHND_PCI_CMN_REG_SET(_regf, _regv, _attr, _val)	\
165298479Sadrian	_BHND_PCI_REG_SET(_regv,				\
166296077Sadrian	    BHND_PCI_COMMON_REG((_regf), _attr ## _MASK),	\
167296077Sadrian	    BHND_PCI_COMMON_REG((_regf), _attr ## _SHIFT),	\
168296077Sadrian	    _val)
169296077Sadrian
170296077Sadrian
171296077Sadrian/**
172296077Sadrian * Evaluates to the offset of a common PCI/PCIe register definition.
173296077Sadrian *
174296077Sadrian * This will trigger a compile-time error if the register is not defined
175296077Sadrian * for all supported PCI/PCIe cores.
176296077Sadrian *
177296077Sadrian * This should be optimized down to a constant value if the register constant
178296077Sadrian * is the same across the register definitions.
179296077Sadrian *
180298479Sadrian * @param _regf The PCI core register format (BHND_PCI_REGFMT_*).
181296077Sadrian * @param _name The base name of the register.
182296077Sadrian */
183296077Sadrian#define	BHND_PCI_COMMON_REG(_regf, _name)	(			\
184298479Sadrian	(_regf) == BHND_PCI_REGFMT_PCI ? BHND_PCI_ ## _name :		\
185296077Sadrian	BHND_PCIE_ ## _name						\
186296077Sadrian)
187296077Sadrian
188296077Sadrian#endif /* _BHND_CORES_PCI_BHND_PCIVAR_H_ */