1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * hdac_i915.c - routines for sync between HD-A core and i915 display driver
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #include <linux/init.h>
7*4882a593Smuzhiyun #include <linux/module.h>
8*4882a593Smuzhiyun #include <linux/pci.h>
9*4882a593Smuzhiyun #include <sound/core.h>
10*4882a593Smuzhiyun #include <sound/hdaudio.h>
11*4882a593Smuzhiyun #include <sound/hda_i915.h>
12*4882a593Smuzhiyun #include <sound/hda_register.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #define IS_HSW_CONTROLLER(pci) (((pci)->device == 0x0a0c) || \
15*4882a593Smuzhiyun ((pci)->device == 0x0c0c) || \
16*4882a593Smuzhiyun ((pci)->device == 0x0d0c) || \
17*4882a593Smuzhiyun ((pci)->device == 0x160c))
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun /**
20*4882a593Smuzhiyun * snd_hdac_i915_set_bclk - Reprogram BCLK for HSW/BDW
21*4882a593Smuzhiyun * @bus: HDA core bus
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun * Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK
24*4882a593Smuzhiyun * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value)
25*4882a593Smuzhiyun * are used to convert CDClk (Core Display Clock) to 24MHz BCLK:
26*4882a593Smuzhiyun * BCLK = CDCLK * M / N
27*4882a593Smuzhiyun * The values will be lost when the display power well is disabled and need to
28*4882a593Smuzhiyun * be restored to avoid abnormal playback speed.
29*4882a593Smuzhiyun *
30*4882a593Smuzhiyun * Call this function at initializing and changing power well, as well as
31*4882a593Smuzhiyun * at ELD notifier for the hotplug.
32*4882a593Smuzhiyun */
snd_hdac_i915_set_bclk(struct hdac_bus * bus)33*4882a593Smuzhiyun void snd_hdac_i915_set_bclk(struct hdac_bus *bus)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun struct drm_audio_component *acomp = bus->audio_component;
36*4882a593Smuzhiyun struct pci_dev *pci = to_pci_dev(bus->dev);
37*4882a593Smuzhiyun int cdclk_freq;
38*4882a593Smuzhiyun unsigned int bclk_m, bclk_n;
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun if (!acomp || !acomp->ops || !acomp->ops->get_cdclk_freq)
41*4882a593Smuzhiyun return; /* only for i915 binding */
42*4882a593Smuzhiyun if (!IS_HSW_CONTROLLER(pci))
43*4882a593Smuzhiyun return; /* only HSW/BDW */
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun cdclk_freq = acomp->ops->get_cdclk_freq(acomp->dev);
46*4882a593Smuzhiyun switch (cdclk_freq) {
47*4882a593Smuzhiyun case 337500:
48*4882a593Smuzhiyun bclk_m = 16;
49*4882a593Smuzhiyun bclk_n = 225;
50*4882a593Smuzhiyun break;
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun case 450000:
53*4882a593Smuzhiyun default: /* default CDCLK 450MHz */
54*4882a593Smuzhiyun bclk_m = 4;
55*4882a593Smuzhiyun bclk_n = 75;
56*4882a593Smuzhiyun break;
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun case 540000:
59*4882a593Smuzhiyun bclk_m = 4;
60*4882a593Smuzhiyun bclk_n = 90;
61*4882a593Smuzhiyun break;
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun case 675000:
64*4882a593Smuzhiyun bclk_m = 8;
65*4882a593Smuzhiyun bclk_n = 225;
66*4882a593Smuzhiyun break;
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun snd_hdac_chip_writew(bus, HSW_EM4, bclk_m);
70*4882a593Smuzhiyun snd_hdac_chip_writew(bus, HSW_EM5, bclk_n);
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hdac_i915_set_bclk);
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun /* returns true if the devices can be connected for audio */
connectivity_check(struct pci_dev * i915,struct pci_dev * hdac)75*4882a593Smuzhiyun static bool connectivity_check(struct pci_dev *i915, struct pci_dev *hdac)
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun struct pci_bus *bus_a = i915->bus, *bus_b = hdac->bus;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun /* directly connected on the same bus */
80*4882a593Smuzhiyun if (bus_a == bus_b)
81*4882a593Smuzhiyun return true;
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun /*
84*4882a593Smuzhiyun * on i915 discrete GPUs with embedded HDA audio, the two
85*4882a593Smuzhiyun * devices are connected via 2nd level PCI bridge
86*4882a593Smuzhiyun */
87*4882a593Smuzhiyun bus_a = bus_a->parent;
88*4882a593Smuzhiyun bus_b = bus_b->parent;
89*4882a593Smuzhiyun if (!bus_a || !bus_b)
90*4882a593Smuzhiyun return false;
91*4882a593Smuzhiyun bus_a = bus_a->parent;
92*4882a593Smuzhiyun bus_b = bus_b->parent;
93*4882a593Smuzhiyun if (bus_a && bus_a == bus_b)
94*4882a593Smuzhiyun return true;
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun return false;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun
i915_component_master_match(struct device * dev,int subcomponent,void * data)99*4882a593Smuzhiyun static int i915_component_master_match(struct device *dev, int subcomponent,
100*4882a593Smuzhiyun void *data)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun struct pci_dev *hdac_pci, *i915_pci;
103*4882a593Smuzhiyun struct hdac_bus *bus = data;
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun if (!dev_is_pci(dev))
106*4882a593Smuzhiyun return 0;
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun hdac_pci = to_pci_dev(bus->dev);
109*4882a593Smuzhiyun i915_pci = to_pci_dev(dev);
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun if (!strcmp(dev->driver->name, "i915") &&
112*4882a593Smuzhiyun subcomponent == I915_COMPONENT_AUDIO &&
113*4882a593Smuzhiyun connectivity_check(i915_pci, hdac_pci))
114*4882a593Smuzhiyun return 1;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun return 0;
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun /* check whether intel graphics is present */
i915_gfx_present(void)120*4882a593Smuzhiyun static bool i915_gfx_present(void)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun static const struct pci_device_id ids[] = {
123*4882a593Smuzhiyun { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
124*4882a593Smuzhiyun .class = PCI_BASE_CLASS_DISPLAY << 16,
125*4882a593Smuzhiyun .class_mask = 0xff << 16 },
126*4882a593Smuzhiyun {}
127*4882a593Smuzhiyun };
128*4882a593Smuzhiyun return pci_dev_present(ids);
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun /**
132*4882a593Smuzhiyun * snd_hdac_i915_init - Initialize i915 audio component
133*4882a593Smuzhiyun * @bus: HDA core bus
134*4882a593Smuzhiyun *
135*4882a593Smuzhiyun * This function is supposed to be used only by a HD-audio controller
136*4882a593Smuzhiyun * driver that needs the interaction with i915 graphics.
137*4882a593Smuzhiyun *
138*4882a593Smuzhiyun * This function initializes and sets up the audio component to communicate
139*4882a593Smuzhiyun * with i915 graphics driver.
140*4882a593Smuzhiyun *
141*4882a593Smuzhiyun * Returns zero for success or a negative error code.
142*4882a593Smuzhiyun */
snd_hdac_i915_init(struct hdac_bus * bus)143*4882a593Smuzhiyun int snd_hdac_i915_init(struct hdac_bus *bus)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun struct drm_audio_component *acomp;
146*4882a593Smuzhiyun int err;
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun if (!i915_gfx_present())
149*4882a593Smuzhiyun return -ENODEV;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun err = snd_hdac_acomp_init(bus, NULL,
152*4882a593Smuzhiyun i915_component_master_match,
153*4882a593Smuzhiyun sizeof(struct i915_audio_component) - sizeof(*acomp));
154*4882a593Smuzhiyun if (err < 0)
155*4882a593Smuzhiyun return err;
156*4882a593Smuzhiyun acomp = bus->audio_component;
157*4882a593Smuzhiyun if (!acomp)
158*4882a593Smuzhiyun return -ENODEV;
159*4882a593Smuzhiyun if (!acomp->ops) {
160*4882a593Smuzhiyun if (!IS_ENABLED(CONFIG_MODULES) ||
161*4882a593Smuzhiyun !request_module("i915")) {
162*4882a593Smuzhiyun /* 60s timeout */
163*4882a593Smuzhiyun wait_for_completion_timeout(&acomp->master_bind_complete,
164*4882a593Smuzhiyun msecs_to_jiffies(60 * 1000));
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun if (!acomp->ops) {
168*4882a593Smuzhiyun dev_info(bus->dev, "couldn't bind with audio component\n");
169*4882a593Smuzhiyun snd_hdac_acomp_exit(bus);
170*4882a593Smuzhiyun return -ENODEV;
171*4882a593Smuzhiyun }
172*4882a593Smuzhiyun return 0;
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hdac_i915_init);
175