blob: 9201caabf8520de8267581db99fb7a240dfd767d [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Aaron Durbin76c37002012-10-30 09:03:43 -05002
3#include <console/console.h>
4#include <device/device.h>
5#include <device/pci.h>
6#include <device/pci_ids.h>
7#include <device/pci_ops.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02008#include <device/mmio.h>
Vladimir Serbinenko75c83872014-09-05 01:01:31 +02009#include <device/azalia_device.h>
Elyes HAOUASbf0970e2019-03-21 11:10:03 +010010
Aaron Durbin76c37002012-10-30 09:03:43 -050011#include "pch.h"
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070012#include "hda_verb.h"
Aaron Durbin76c37002012-10-30 09:03:43 -050013
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080014static void codecs_init(u8 *base, u32 codec_mask)
Aaron Durbin76c37002012-10-30 09:03:43 -050015{
16 int i;
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070017
18 /* Can support up to 4 codecs */
Aaron Durbin76c37002012-10-30 09:03:43 -050019 for (i = 3; i >= 0; i--) {
20 if (codec_mask & (1 << i))
Angel Pons94b37352021-11-10 18:05:12 +010021 azalia_codec_init(base, i, cim_verb_data, cim_verb_data_size);
Aaron Durbin76c37002012-10-30 09:03:43 -050022 }
23
Vladimir Serbinenko75c83872014-09-05 01:01:31 +020024 if (pc_beep_verbs_size)
Angel Pons5300b032021-11-10 17:44:51 +010025 azalia_program_verb_table(base, pc_beep_verbs, pc_beep_verbs_size);
Aaron Durbin76c37002012-10-30 09:03:43 -050026}
27
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080028static void azalia_pch_init(struct device *dev, u8 *base)
Aaron Durbin76c37002012-10-30 09:03:43 -050029{
Aaron Durbin76c37002012-10-30 09:03:43 -050030 u8 reg8;
31 u16 reg16;
32 u32 reg32;
33
Angel Pons8963f7d2020-10-24 12:20:28 +020034 if (RCBA32(0x2030) & (1 << 31)) {
Kyösti Mälkki386b3e62013-07-26 08:52:49 +030035 reg32 = pci_read_config32(dev, 0x120);
Aaron Durbin76c37002012-10-30 09:03:43 -050036 reg32 &= 0xf8ffff01;
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070037 reg32 |= (1 << 25);
Aaron Durbin76c37002012-10-30 09:03:43 -050038 reg32 |= RCBA32(0x2030) & 0xfe;
Kyösti Mälkki386b3e62013-07-26 08:52:49 +030039 pci_write_config32(dev, 0x120, reg32);
Aaron Durbin76c37002012-10-30 09:03:43 -050040
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070041 if (!pch_is_lp()) {
Angel Ponsbf9bc502020-06-08 00:12:43 +020042 pci_and_config16(dev, 0x78, ~(1 << 11));
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070043 }
Aaron Durbin76c37002012-10-30 09:03:43 -050044 } else
45 printk(BIOS_DEBUG, "Azalia: V1CTL disabled.\n");
46
Kyösti Mälkki386b3e62013-07-26 08:52:49 +030047 reg32 = pci_read_config32(dev, 0x114);
Aaron Durbin76c37002012-10-30 09:03:43 -050048 reg32 &= ~0xfe;
Kyösti Mälkki386b3e62013-07-26 08:52:49 +030049 pci_write_config32(dev, 0x114, reg32);
Aaron Durbin76c37002012-10-30 09:03:43 -050050
51 // Set VCi enable bit
Angel Ponsbf9bc502020-06-08 00:12:43 +020052 if (pci_read_config32(dev, 0x120) & ((1 << 24) | (1 << 25) | (1 << 26))) {
Kyösti Mälkki386b3e62013-07-26 08:52:49 +030053 reg32 = pci_read_config32(dev, 0x120);
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070054 if (pch_is_lp())
Angel Pons8963f7d2020-10-24 12:20:28 +020055 reg32 &= ~(1 << 31);
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070056 else
Angel Pons8963f7d2020-10-24 12:20:28 +020057 reg32 |= (1 << 31);
Kyösti Mälkki386b3e62013-07-26 08:52:49 +030058 pci_write_config32(dev, 0x120, reg32);
Aaron Durbin76c37002012-10-30 09:03:43 -050059 }
60
Aaron Durbin76c37002012-10-30 09:03:43 -050061 reg8 = pci_read_config8(dev, 0x43);
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070062 if (pch_is_lp())
63 reg8 &= ~(1 << 6);
64 else
65 reg8 |= (1 << 4);
Aaron Durbin76c37002012-10-30 09:03:43 -050066 pci_write_config8(dev, 0x43, reg8);
67
Angel Ponsbf9bc502020-06-08 00:12:43 +020068 if (!pch_is_lp())
69 pci_or_config32(dev, 0xc0, 1 << 17);
Aaron Durbin76c37002012-10-30 09:03:43 -050070
71 /* Additional programming steps */
72 reg32 = pci_read_config32(dev, 0xc4);
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070073 if (pch_is_lp())
74 reg32 |= (1 << 24);
75 else
76 reg32 |= (1 << 14);
Aaron Durbin76c37002012-10-30 09:03:43 -050077 pci_write_config32(dev, 0xc4, reg32);
78
Angel Ponsbf9bc502020-06-08 00:12:43 +020079 if (!pch_is_lp())
Angel Pons8963f7d2020-10-24 12:20:28 +020080 pci_and_config32(dev, 0xd0, ~(1 << 31));
Aaron Durbin76c37002012-10-30 09:03:43 -050081
Angel Ponsbf9bc502020-06-08 00:12:43 +020082 // Docking not supported
83 pci_and_config8(dev, 0x4d, (u8)~(1 << 7)); // Docking Status
Aaron Durbin76c37002012-10-30 09:03:43 -050084
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070085 if (pch_is_lp()) {
86 reg16 = read32(base + 0x0012);
87 reg16 |= (1 << 0);
88 write32(base + 0x0012, reg16);
89
90 /* disable Auto Voltage Detector */
Angel Ponsbf9bc502020-06-08 00:12:43 +020091 pci_or_config8(dev, 0x42, 1 << 2);
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070092 }
93}
94
95static void azalia_init(struct device *dev)
96{
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080097 u8 *base;
Duncan Laurie0a7c49e2013-06-20 12:40:55 -070098 struct resource *res;
99 u32 codec_mask;
Duncan Laurie0a7c49e2013-06-20 12:40:55 -0700100
101 /* Find base address */
Angel Ponsf32ae102021-11-03 13:07:14 +0100102 res = probe_resource(dev, PCI_BASE_ADDRESS_0);
Duncan Laurie0a7c49e2013-06-20 12:40:55 -0700103 if (!res)
104 return;
105
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800106 base = res2mmio(res, 0, 0);
107 printk(BIOS_DEBUG, "Azalia: base = %p\n", base);
Duncan Laurie0a7c49e2013-06-20 12:40:55 -0700108
109 /* Set Bus Master */
Elyes HAOUAS73ae0762020-04-28 10:13:05 +0200110 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER);
Duncan Laurie0a7c49e2013-06-20 12:40:55 -0700111
112 azalia_pch_init(dev, base);
113
114 codec_mask = hda_codec_detect(base);
Aaron Durbin76c37002012-10-30 09:03:43 -0500115
116 if (codec_mask) {
117 printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask);
Duncan Laurie0a7c49e2013-06-20 12:40:55 -0700118 codecs_init(base, codec_mask);
Aaron Durbin76c37002012-10-30 09:03:43 -0500119 }
Aaron Durbin76c37002012-10-30 09:03:43 -0500120}
121
Angel Ponsc1301dd2021-03-18 20:35:19 +0100122static void azalia_final(struct device *dev)
123{
124 /* Set HDCFG.BCLD */
125 pci_or_config16(dev, 0x40, 1 << 1);
126}
127
Aaron Durbin76c37002012-10-30 09:03:43 -0500128static struct device_operations azalia_ops = {
129 .read_resources = pci_dev_read_resources,
130 .set_resources = pci_dev_set_resources,
131 .enable_resources = pci_dev_enable_resources,
132 .init = azalia_init,
Angel Ponsc1301dd2021-03-18 20:35:19 +0100133 .final = azalia_final,
Angel Pons1fc0edd2020-05-31 00:03:28 +0200134 .ops_pci = &pci_dev_ops_pci,
Aaron Durbin76c37002012-10-30 09:03:43 -0500135};
136
Felix Singer4ea08f92020-11-20 12:56:44 +0000137static const unsigned short pci_device_ids[] = {
138 PCI_DEVICE_ID_INTEL_LPT_H_AUDIO,
139 PCI_DEVICE_ID_INTEL_LPT_LP_AUDIO,
140 0
141};
Aaron Durbin76c37002012-10-30 09:03:43 -0500142
143static const struct pci_driver pch_azalia __pci_driver = {
144 .ops = &azalia_ops,
145 .vendor = PCI_VENDOR_ID_INTEL,
146 .devices = pci_device_ids,
147};