blob: 27edae1f4bfa5f0faa003c66fd51e827f7853b8e [file] [log] [blame]
Aaron Durbinc626b742013-11-12 16:40:33 -06001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 Google Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Aaron Durbinc626b742013-11-12 16:40:33 -060014 */
15
16
Duncan Laurie430bf0d2013-12-10 14:37:42 -080017#include <cbmem.h>
Aaron Durbinc626b742013-11-12 16:40:33 -060018#include <console/console.h>
Duncan Laurie430bf0d2013-12-10 14:37:42 -080019#include <device/device.h>
20#include <device/pci.h>
21#include <device/pci_ids.h>
Aaron Durbinc626b742013-11-12 16:40:33 -060022#include <reg_script.h>
23
Julius Werner18ea2d32014-10-07 16:42:17 -070024#include <soc/iosf.h>
25#include <soc/nvs.h>
26#include <soc/ramstage.h>
Aaron Durbinc626b742013-11-12 16:40:33 -060027
28static const struct reg_script scc_start_dll[] = {
29 /* Configure master DLL. */
30 REG_IOSF_WRITE(IOSF_PORT_SCORE, 0x4964, 0x00078000),
31 /* Configure Swing,FSM for Master DLL */
32 REG_IOSF_WRITE(IOSF_PORT_SCORE, 0x4970, 0x00000133),
33 /* Run+Local Reset on Master DLL */
34 REG_IOSF_WRITE(IOSF_PORT_SCORE, 0x4970, 0x00001933),
35 REG_SCRIPT_END,
36};
37
38static const struct reg_script scc_after_dll[] = {
39 /* Configure Write Path */
40 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x4954, ~0x7fff, 0x35ad),
41 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x4958, ~0x7fff, 0x35ad),
42 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x495c, ~0x7fff, 0x35ad),
43 /* Configure Read Path */
44 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x43e4, ~0x7fff, 0x35ad),
45 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x4324, ~0x7fff, 0x35ad),
46 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x42b4, ~0x7fff, 0x35ad),
47 /* eMMC 4.5 TX and RX DLL */
48 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x49a4, ~0x1f001f, 0xa000d),
49 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x49a8, ~0x1f001f, 0xd000d),
50 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x49ac, ~0x1f001f, 0xd000d),
51 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x49b0, ~0x1f001f, 0xd000d),
52 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x49b4, ~0x1f001f, 0xd000d),
53 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x49b8, ~0x1, 0x0),
54 /* cfio_regs_mmc1_ELECTRICAL.nslew/pslew */
55 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x48c0, ~0x3c, 0x0),
56 REG_IOSF_RMW(IOSF_PORT_SCORE, 0x48c4, ~0x3c, 0x0),
57 /*
58 * iosf2ocp_private.GENREGRW1.cr_clock_enable_clk_ocp = 01
59 * iosf2ocp_private.GENREGRW1.cr_clock_enable_clk_xin = 01
60 */
61 REG_IOSF_RMW(IOSF_PORT_SCC, 0x600, ~0xf, 0x5),
62 /* Enable IOSF Snoop */
63 REG_IOSF_OR(IOSF_PORT_SCC, 0x00, (1 << 7)),
64 /* SDIO 3V Support. */
65 REG_IOSF_RMW(IOSF_PORT_SCC, 0x600, ~0x30, 0x30),
66 REG_SCRIPT_END,
67};
68
69void baytrail_init_scc(void)
70{
71 uint32_t dll_values;
72
73 printk(BIOS_DEBUG, "Initializing sideband SCC registers.\n");
74
75 /* Common Sideband Initialization for SCC */
76 reg_script_run(scc_start_dll);
77
78 /* Override Slave Path - populate DLL settings. */
79 dll_values = iosf_score_read(0x496c) & 0x7ffff;
80 dll_values |= iosf_score_read(0x4950) & ~0xfffff;
81 iosf_score_write(0x4950, dll_values | (1 << 19));
82
83 reg_script_run(scc_after_dll);
84}
Duncan Laurie430bf0d2013-12-10 14:37:42 -080085
86void scc_enable_acpi_mode(device_t dev, int iosf_reg, int nvs_index)
87{
88 struct reg_script ops[] = {
Duncan Laurie430bf0d2013-12-10 14:37:42 -080089 /* Disable PCI interrupt, enable Memory and Bus Master */
90 REG_PCI_OR32(PCI_COMMAND,
91 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | (1<<10)),
92 /* Enable ACPI mode */
93 REG_IOSF_OR(IOSF_PORT_SCC, iosf_reg,
94 SCC_CTL_PCI_CFG_DIS | SCC_CTL_ACPI_INT_EN),
95 REG_SCRIPT_END
96 };
97 struct resource *bar;
98 global_nvs_t *gnvs;
99
100 /* Find ACPI NVS to update BARs */
101 gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS);
102 if (!gnvs) {
103 printk(BIOS_ERR, "Unable to locate Global NVS\n");
104 return;
105 }
106
107 /* Save BAR0 and BAR1 to ACPI NVS */
108 bar = find_resource(dev, PCI_BASE_ADDRESS_0);
109 if (bar)
110 gnvs->dev.scc_bar0[nvs_index] = (u32)bar->base;
111
112 bar = find_resource(dev, PCI_BASE_ADDRESS_1);
113 if (bar)
114 gnvs->dev.scc_bar1[nvs_index] = (u32)bar->base;
115
116 /* Device is enabled in ACPI mode */
117 gnvs->dev.scc_en[nvs_index] = 1;
118
119 /* Put device in ACPI mode */
Aaron Durbin616f3942013-12-10 17:12:44 -0800120 reg_script_run_on_dev(dev, ops);
Duncan Laurie430bf0d2013-12-10 14:37:42 -0800121}