diff options
-rw-r--r-- | arch/x86/cpu/intel_common/fast_spi.c | 19 | ||||
-rw-r--r-- | arch/x86/dts/chromebook_coral.dts | 15 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h | 17 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h | 72 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-baytrail/acpi/lpc.asl | 24 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-quark/acpi/southcluster.asl | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/arch-tangier/acpi/southcluster.asl | 99 | ||||
-rw-r--r-- | arch/x86/include/asm/fast_spi.h | 19 | ||||
-rw-r--r-- | arch/x86/include/asm/mrccache.h | 15 | ||||
-rw-r--r-- | arch/x86/lib/mrccache.c | 35 | ||||
-rw-r--r-- | arch/x86/lib/spl.c | 4 | ||||
-rw-r--r-- | board/intel/minnowmax/Kconfig | 3 | ||||
-rw-r--r-- | drivers/spi/ich.c | 103 |
14 files changed, 314 insertions, 115 deletions
diff --git a/arch/x86/cpu/intel_common/fast_spi.c b/arch/x86/cpu/intel_common/fast_spi.c index a6e3d0a5bf..5d3944dee2 100644 --- a/arch/x86/cpu/intel_common/fast_spi.c +++ b/arch/x86/cpu/intel_common/fast_spi.c @@ -31,21 +31,30 @@ static ulong fast_spi_get_bios_region(struct fast_spi_regs *regs, return bios_start; } +int fast_spi_get_bios_mmap_regs(struct fast_spi_regs *regs, ulong *map_basep, + uint *map_sizep, uint *offsetp) +{ + ulong base; + + base = fast_spi_get_bios_region(regs, map_sizep); + *map_basep = (u32)-*map_sizep - base; + *offsetp = base; + + return 0; +} + int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep, uint *offsetp) { struct fast_spi_regs *regs; - ulong bar, base, mmio_base; + ulong bar, mmio_base; /* Special case to find mapping without probing the device */ pci_x86_read_config(pdev, PCI_BASE_ADDRESS_0, &bar, PCI_SIZE_32); mmio_base = bar & PCI_BASE_ADDRESS_MEM_MASK; regs = (struct fast_spi_regs *)mmio_base; - base = fast_spi_get_bios_region(regs, map_sizep); - *map_basep = (u32)-*map_sizep - base; - *offsetp = base; - return 0; + return fast_spi_get_bios_mmap_regs(regs, map_basep, map_sizep, offsetp); } int fast_spi_early_init(pci_dev_t pdev, ulong mmio_base) diff --git a/arch/x86/dts/chromebook_coral.dts b/arch/x86/dts/chromebook_coral.dts index dea35b73a0..965d9f387d 100644 --- a/arch/x86/dts/chromebook_coral.dts +++ b/arch/x86/dts/chromebook_coral.dts @@ -516,6 +516,11 @@ 20 23 22 21 18 19 16 17 /* DQB[7:15] pins of LPDDR4 module with offset of 16 */ 25 28 30 31 26 27 24 29>; + + fspm,dimm0-spd-address = <0>; + fspm,dimm1-spd-address = <0>; + fspm,skip-cse-rbp = <1>; + fspm,enable-s3-heci2 = <0>; }; &fsp_s { @@ -594,13 +599,9 @@ fsps,emmc-rx-cmd-data-cntl1 = <0x00181717>; fsps,emmc-rx-cmd-data-cntl2 = <0x10008>; - /* Enable Audio Clock and Power gating */ - fsps,hd-audio-clk-gate = <1>; - fsps,hd-audio-pwr-gate = <1>; - fsps,bios-cfg-lock-down = <1>; - - /* Enable lpss s0ix */ - fsps,lpss-s0ix-enable = <1>; + /* Enable WiFi */ + fsps,pcie-root-port-en = [01 00 00 00 00 00]; + fsps,pcie-rp-hot-plug = [00 00 00 00 00 00]; fsps,skip-mp-init = <1>; fsps,spi-eiss = <0>; diff --git a/arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h b/arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h index a77964f30c..5275b75f3b 100644 --- a/arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h +++ b/arch/x86/include/asm/arch-apollolake/fsp/fsp_m_upd.h @@ -34,7 +34,15 @@ struct __packed fsp_ram_channel { u8 odt_levels; }; +/** + * struct fsp_m_config - FSP-M configuration + * + * Note that headers precede this and are 64 bytes long. The hex offsets + * mentioned in this file are relative to the start of the header, the same + * convention used in Intel's APL FSP header file. + */ struct __packed fsp_m_config { + /* 0x40 */ u32 serial_debug_port_address; u8 serial_debug_port_type; u8 serial_debug_port_device; @@ -49,6 +57,7 @@ struct __packed fsp_m_config { u8 profile; u8 memory_down; + /* 0x50 */ u8 ddr3_l_page_size; u8 ddr3_lasr; u8 scrambler_support; @@ -62,6 +71,7 @@ struct __packed fsp_m_config { u16 memory_size_limit; u16 low_memory_max_value; + /* 0x60 */ u16 high_memory_max_value; u8 disable_fast_boot; u8 dimm0_spd_address; @@ -73,6 +83,7 @@ struct __packed fsp_m_config { u32 msg_level_mask; u8 unused_upd_space0[4]; + /* 0x110 */ u8 pre_mem_gpio_table_pin_num[4]; u32 pre_mem_gpio_table_ptr; u8 pre_mem_gpio_table_entry_num; @@ -81,8 +92,10 @@ struct __packed fsp_m_config { u8 mrc_data_saving; u32 oem_loading_base; + /* 0x120 */ u8 oem_file_name[16]; + /* 0x130 */ void *mrc_boot_data_ptr; u8 e_mmc_trace_len; u8 skip_cse_rbp; @@ -94,20 +107,20 @@ struct __packed fsp_m_config { u8 msc1_wrap; u32 msc0_size; + /* 0x140 */ u32 msc1_size; u8 pti_mode; u8 pti_training; u8 pti_speed; u8 punit_mlvl; - u8 pmc_mlvl; u8 sw_trace_en; u8 periodic_retraining_disable; u8 enable_reset_system; - u8 enable_s3_heci2; u8 unused_upd_space1[3]; + /* 0x150 */ void *variable_nvs_buffer_ptr; u8 reserved_fspm_upd[12]; }; diff --git a/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h b/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h index 87596ffd9d..451a7a254a 100644 --- a/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h +++ b/arch/x86/include/asm/arch-apollolake/fsp/fsp_s_upd.h @@ -9,7 +9,15 @@ #ifndef __ASSEMBLY__ #include <asm/fsp2/fsp_api.h> +/** + * struct fsp_s_config - FSP-S configuration + * + * Note that struct fsp_upd_header preceeds this and is 32 bytes long. The + * hex offsets mentioned in this file are relative to the start of the header, + * the same convention used in Intel's APL FSP header file. + */ struct __packed fsp_s_config { + /* 0x20 */ u8 active_processor_cores; u8 disable_core1; u8 disable_core2; @@ -26,6 +34,8 @@ struct __packed fsp_s_config { u8 c_state_auto_demotion; u8 c_state_un_demotion; u8 max_core_c_state; + + /* 0x30 */ u8 pkg_c_state_demotion; u8 pkg_c_state_un_demotion; u8 turbo_mode; @@ -36,6 +46,8 @@ struct __packed fsp_s_config { u8 ipu_acpi_mode; u8 force_wake; u32 gtt_mm_adr; + + /* 0x40 */ u32 gm_adr; u8 pavp_lock; u8 graphics_freq_modify; @@ -49,6 +61,8 @@ struct __packed fsp_s_config { u8 power_gating; u8 unit_level_clock_gating; u8 fast_boot; + + /* 0x50 */ u8 dyn_sr; u8 sa_ipu_enable; u8 pm_support; @@ -56,6 +70,8 @@ struct __packed fsp_s_config { u32 logo_size; u32 logo_ptr; u32 graphics_config_ptr; + + /* 0x60 */ u8 pavp_enable; u8 pavp_pr3; u8 cd_clock; @@ -78,6 +94,8 @@ struct __packed fsp_s_config { u8 hda_enable; u8 dsp_enable; u8 pme; + + /* 0x90 */ u8 hd_audio_io_buffer_ownership; u8 hd_audio_io_buffer_voltage; u8 hd_audio_vc_type; @@ -94,6 +112,8 @@ struct __packed fsp_s_config { u8 hmt; u8 hd_audio_pwr_gate; u8 hd_audio_clk_gate; + + /* 0xa0 */ u32 dsp_feature_mask; u32 dsp_pp_module_mask; u8 bios_cfg_lock_down; @@ -104,6 +124,8 @@ struct __packed fsp_s_config { u8 hpet_function_number; u8 io_apic_bdf_valid; u8 io_apic_bus_number; + + /* 0xb0 */ u8 io_apic_device_number; u8 io_apic_function_number; u8 io_apic_entry24_119; @@ -124,6 +146,8 @@ struct __packed fsp_s_config { u8 i2c2_enable; u8 i2c3_enable; u8 i2c4_enable; + + /* 0xd0 */ u8 i2c5_enable; u8 i2c6_enable; u8 i2c7_enable; @@ -137,6 +161,8 @@ struct __packed fsp_s_config { u8 os_dbg_enable; u8 dci_en; u32 uart2_kernel_debug_base_address; + + /* 0xe0 */ u8 pcie_clock_gating_disabled; u8 pcie_root_port8xh_decode; u8 pcie8xh_decode_port_index; @@ -150,6 +176,8 @@ struct __packed fsp_s_config { u8 pcie_rp_pm_sci[6]; u8 pcie_rp_ext_sync[6]; u8 pcie_rp_transmitter_half_swing[6]; + + /* 0x110 */ u8 pcie_rp_acs_enabled[6]; u8 pcie_rp_clk_req_supported[6]; u8 pcie_rp_clk_req_number[6]; @@ -158,6 +186,8 @@ struct __packed fsp_s_config { u8 pme_interrupt[6]; u8 unsupported_request_report[6]; u8 fatal_error_report[6]; + + /* 0x140 */ u8 no_fatal_error_report[6]; u8 correctable_error_report[6]; u8 system_error_on_fatal_error[6]; @@ -166,6 +196,8 @@ struct __packed fsp_s_config { u8 pcie_rp_speed[6]; u8 physical_slot_number[6]; u8 pcie_rp_completion_timeout[6]; + + /* 0x170 */ u8 ptm_enable[6]; u8 pcie_rp_aspm[6]; u8 pcie_rp_l1_substates[6]; @@ -173,6 +205,8 @@ struct __packed fsp_s_config { u8 pcie_rp_ltr_config_lock[6]; u8 pme_b0_s5_dis; u8 pci_clock_run; + + /* 0x190 */ u8 timer8254_clk_setting; u8 enable_sata; u8 sata_mode; @@ -185,6 +219,8 @@ struct __packed fsp_s_config { u8 sata_ports_dev_slp[2]; u8 sata_ports_hot_plug[2]; u8 sata_ports_interlock_sw[2]; + + /* 0x1a0 */ u8 sata_ports_external[2]; u8 sata_ports_spin_up[2]; u8 sata_ports_solid_state_drive[2]; @@ -192,6 +228,8 @@ struct __packed fsp_s_config { u8 sata_ports_dm_val[2]; u8 unused_upd_space3[2]; u16 sata_ports_dito_val[2]; + + /* 0x1b0 */ u16 sub_system_vendor_id; u16 sub_system_id; u8 crid_settings; @@ -206,6 +244,8 @@ struct __packed fsp_s_config { u8 sirq_mode; u8 start_frame_pulse; u8 smbus_enable; + + /* 0x1c0 */ u8 arp_enable; u8 unused_upd_space4; u16 num_rsvd_smbus_addresses; @@ -215,10 +255,14 @@ struct __packed fsp_s_config { u8 usb30_mode; u8 unused_upd_space5[1]; u8 port_usb20_enable[8]; + + /* 0x250 */ u8 port_us20b_over_current_pin[8]; u8 usb_otg; u8 hsic_support_enable; u8 port_usb30_enable[6]; + + /* 0x260 */ u8 port_us30b_over_current_pin[6]; u8 ssic_port_enable[2]; u16 dlane_pwr_gating; @@ -227,9 +271,13 @@ struct __packed fsp_s_config { u16 reset_wait_timer; u8 rtc_lock; u8 sata_test_mode; + + /* 0x270 */ u8 ssic_rate[2]; u16 dynamic_power_gating; u16 pcie_rp_ltr_max_snoop_latency[6]; + + /* 0x280 */ u8 pcie_rp_snoop_latency_override_mode[6]; u8 unused_upd_space6[2]; u16 pcie_rp_snoop_latency_override_value[6]; @@ -240,45 +288,69 @@ struct __packed fsp_s_config { u8 pcie_rp_non_snoop_latency_override_mode[6]; u8 tco_timer_halt_lock; u8 pwr_btn_override_period; + + /* 0x2b0 */ u16 pcie_rp_non_snoop_latency_override_value[6]; u8 pcie_rp_non_snoop_latency_override_multiplier[6]; u8 pcie_rp_slot_power_limit_scale[6]; u8 pcie_rp_slot_power_limit_value[6]; u8 disable_native_power_button; u8 power_butter_debounce_mode; + + /* 0x2d0 */ u32 sdio_tx_cmd_cntl; u32 sdio_tx_data_cntl1; u32 sdio_tx_data_cntl2; u32 sdio_rx_cmd_data_cntl1; + + /* 0x2e0 */ u32 sdio_rx_cmd_data_cntl2; u32 sdcard_tx_cmd_cntl; u32 sdcard_tx_data_cntl1; u32 sdcard_tx_data_cntl2; + + /* 0x2f0 */ u32 sdcard_rx_cmd_data_cntl1; u32 sdcard_rx_strobe_cntl; u32 sdcard_rx_cmd_data_cntl2; u32 emmc_tx_cmd_cntl; + + /* 0x300 */ u32 emmc_tx_data_cntl1; u32 emmc_tx_data_cntl2; u32 emmc_rx_cmd_data_cntl1; u32 emmc_rx_strobe_cntl; + + /* 0x310 */ u32 emmc_rx_cmd_data_cntl2; u32 emmc_master_sw_cntl; u8 pcie_rp_selectable_deemphasis[6]; u8 monitor_mwait_enable; u8 hd_audio_dsp_uaa_compliance; + + /* 0x320 */ u32 ipc[4]; + + /* 0x330 */ u8 sata_ports_disable_dynamic_pg[2]; u8 init_s3_cpu; u8 skip_punit_init; u8 unused_upd_space7[4]; u8 port_usb20_per_port_tx_pe_half[8]; + + /* 0x340 */ u8 port_usb20_per_port_pe_txi_set[8]; u8 port_usb20_per_port_txi_set[8]; + + /* 0x350 */ u8 port_usb20_hs_skew_sel[8]; u8 port_usb20_i_usb_tx_emphasis_en[8]; + + /* 0x360 */ u8 port_usb20_per_port_rxi_set[8]; u8 port_usb20_hs_npre_drv_sel[8]; + + /* 0x370 */ u8 reserved_fsps_upd[16]; }; diff --git a/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl b/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl index 08b2f53132..69455d90da 100644 --- a/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl +++ b/arch/x86/include/asm/arch-baytrail/acpi/lpc.asl @@ -136,20 +136,20 @@ Device (LPCB) Store(0, C1EN) } - Method(_CRS, 0, Serialized) + Name(BUF0, ResourceTemplate() { - Name(BUF0, ResourceTemplate() - { - IO(Decode16, 0x03f8, 0x03f8, 0x01, 0x08) - IRQNoFlags() { 3 } - }) - - Name(BUF1, ResourceTemplate() - { - IO(Decode16, 0x03f8, 0x03f8, 0x01, 0x08) - IRQNoFlags() { 4 } - }) + IO(Decode16, 0x03f8, 0x03f8, 0x01, 0x08) + IRQNoFlags() { 3 } + }) + Name(BUF1, ResourceTemplate() + { + IO(Decode16, 0x03f8, 0x03f8, 0x01, 0x08) + IRQNoFlags() { 4 } + }) + + Method(_CRS, 0, Serialized) + { If (LLessEqual(SRID, 0x04)) { Return (BUF0) } Else { diff --git a/arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl b/arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl index 2a1c31cdc4..3b220c7ac2 100644 --- a/arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl +++ b/arch/x86/include/asm/arch-baytrail/acpi/southcluster.asl @@ -11,7 +11,7 @@ Device (PCI0) Name(_HID, EISAID("PNP0A08")) /* PCIe */ Name(_CID, EISAID("PNP0A03")) /* PCI */ - Name(_ADR, 0) + Name(_UID, 0) Name(_BBN, 0) Name(MCRS, ResourceTemplate() diff --git a/arch/x86/include/asm/arch-quark/acpi/southcluster.asl b/arch/x86/include/asm/arch-quark/acpi/southcluster.asl index fe9edc1a87..384dab25bd 100644 --- a/arch/x86/include/asm/arch-quark/acpi/southcluster.asl +++ b/arch/x86/include/asm/arch-quark/acpi/southcluster.asl @@ -8,7 +8,7 @@ Device (PCI0) Name(_HID, EISAID("PNP0A08")) /* PCIe */ Name(_CID, EISAID("PNP0A03")) /* PCI */ - Name(_ADR, 0) + Name(_UID, 0) Name(_BBN, 0) Name(MCRS, ResourceTemplate() diff --git a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl index f088fe3cf5..df66625930 100644 --- a/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl +++ b/arch/x86/include/asm/arch-tangier/acpi/southcluster.asl @@ -10,7 +10,7 @@ Device (PCI0) Name (_HID, EISAID("PNP0A08")) /* PCIe */ Name (_CID, EISAID("PNP0A03")) /* PCI */ - Name (_ADR, Zero) + Name (_UID, Zero) Name (_BBN, Zero) Name (MCRS, ResourceTemplate() @@ -338,12 +338,12 @@ Device (PCI0) { Name (_ADR, Zero) + Name (PCKG, Package () { + Buffer (0x14) {} + }) + /* GPLD: Generate Port Location Data (PLD) */ Method (GPLD, 1, Serialized) { - Name (PCKG, Package () { - Buffer (0x14) {} - }) - /* REV: Revision 0x02 for ACPI 5.0 */ CreateField (DerefOf (Index (PCKG, Zero)), Zero, 0x07, REV) Store (0x0002, REV) @@ -401,20 +401,21 @@ Device (PCI0) Return (STA_VISIBLE) } + Name (RBUF, ResourceTemplate() + { + UartSerialBus(0x0001C200, DataBitsEight, StopBitsOne, + 0xFC, LittleEndian, ParityTypeNone, FlowControlHardware, + 0x20, 0x20, "\\_SB.PCI0.HSU0", 0, ResourceConsumer, , ) + GpioInt(Level, ActiveHigh, Exclusive, PullNone, 0, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 185 } + GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 184 } + GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, + "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 71 } + }) + Method (_CRS, 0, Serialized) { - Name (RBUF, ResourceTemplate() - { - UartSerialBus(0x0001C200, DataBitsEight, StopBitsOne, - 0xFC, LittleEndian, ParityTypeNone, FlowControlHardware, - 0x20, 0x20, "\\_SB.PCI0.HSU0", 0, ResourceConsumer, , ) - GpioInt(Level, ActiveHigh, Exclusive, PullNone, 0, - "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 185 } - GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, - "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 184 } - GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, - "\\_SB.PCI0.GPIO", 0, ResourceConsumer, , ) { 71 } - }) Return (RBUF) } @@ -440,7 +441,6 @@ Device (PCI0) Device (PMIC) { - Name (_ADR, Zero) Name (_HID, "INTC100E") Name (_CID, "INTC100E") Name (_DDN, "Basin Cove PMIC") @@ -454,33 +454,34 @@ Device (PCI0) Return (STA_VISIBLE) } + Name (RBUF, ResourceTemplate() + { + /* + * Shadow registers in SRAM for PMIC: + * SRAM PMIC register + * -------------------- + * 0x00- Unknown + * 0x03 THRMIRQ (0x04) + * 0x04 BCUIRQ (0x05) + * 0x05 ADCIRQ (0x06) + * 0x06 CHGRIRQ0 (0x07) + * 0x07 CHGRIRQ1 (0x08) + * 0x08- Unknown + * 0x0a PBSTATUS (0x27) + * 0x0b- Unknown + */ + Memory32Fixed(ReadWrite, 0xFFFFF610, 0x00000010) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 30 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 23 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 52 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 51 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 50 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 27 } + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 49 } + }) + Method (_CRS, 0, Serialized) { - Name (RBUF, ResourceTemplate() - { - /* - * Shadow registers in SRAM for PMIC: - * SRAM PMIC register - * -------------------- - * 0x00- Unknown - * 0x03 THRMIRQ (0x04) - * 0x04 BCUIRQ (0x05) - * 0x05 ADCIRQ (0x06) - * 0x06 CHGRIRQ0 (0x07) - * 0x07 CHGRIRQ1 (0x08) - * 0x08- Unknown - * 0x0a PBSTATUS (0x27) - * 0x0b- Unknown - */ - Memory32Fixed(ReadWrite, 0xFFFFF610, 0x00000010) - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 30 } - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 23 } - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 52 } - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 51 } - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 50 } - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 27 } - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 49 } - }) Return (RBUF) } @@ -519,7 +520,6 @@ Device (PCI0) Device (GDMA) { Name (_ADR, 0x00150000) - Name (_HID, "808611A2") Name (_UID, Zero) Method (_STA, 0, NotSerialized) @@ -527,13 +527,14 @@ Device (PCI0) Return (STA_VISIBLE) } + Name (RBUF, ResourceTemplate () + { + Memory32Fixed(ReadWrite, 0xFF192000, 0x00001000) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 32 } + }) + Method (_CRS, 0, Serialized) { - Name (RBUF, ResourceTemplate () - { - Memory32Fixed(ReadWrite, 0xFF192000, 0x00001000) - Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 32 } - }) Return (RBUF) } } diff --git a/arch/x86/include/asm/fast_spi.h b/arch/x86/include/asm/fast_spi.h index 47c1da80d7..7a81d4f05c 100644 --- a/arch/x86/include/asm/fast_spi.h +++ b/arch/x86/include/asm/fast_spi.h @@ -64,6 +64,25 @@ check_member(fast_spi_regs, ptdata, 0xd0); int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep, uint *offsetp); +/** + * fast_spi_get_bios_mmap_regs() - Get memory map for SPI flash given regs + * + * @regs: SPI registers to use + * @map_basep: Returns base memory address for mapped SPI + * @map_sizep: Returns size of mapped SPI + * @offsetp: Returns start offset of SPI flash where the map works + * correctly (offsets before this are not visible) + * @return 0 (always) + */ +int fast_spi_get_bios_mmap_regs(struct fast_spi_regs *regs, ulong *map_basep, + uint *map_sizep, uint *offsetp); + +/** + * fast_spi_early_init() - Set up a BAR to use SPI early in U-Boot + * + * @pdev: PCI device to use (this is the Fast SPI device) + * @mmio_base: MMIO base to use to access registers + */ int fast_spi_early_init(pci_dev_t pdev, ulong mmio_base); #endif /* ASM_FAST_SPI_H */ diff --git a/arch/x86/include/asm/mrccache.h b/arch/x86/include/asm/mrccache.h index d6b7529073..b60d1171f7 100644 --- a/arch/x86/include/asm/mrccache.h +++ b/arch/x86/include/asm/mrccache.h @@ -66,19 +66,12 @@ int mrccache_reserve(void); * mrccache_get_region() - get MRC region on the SPI flash * * This gets MRC region whose offset and size are described in the device tree - * as a subnode to the SPI flash. If a non-NULL device pointer is supplied, - * this also probes the SPI flash device and returns its device pointer for - * the caller to use later. - * - * Be careful when calling this routine with a non-NULL device pointer: - * - driver model initialization must be complete - * - calling in the pre-relocation phase may bring some side effects during - * the SPI flash device probe (eg: for SPI controllers on a PCI bus, it - * triggers PCI bus enumeration during which insufficient memory issue - * might be exposed and it causes subsequent SPI flash probe fails). + * as a subnode to the SPI flash. This tries to find the SPI flash device + * (without probing it), falling back to looking for the devicetree node if + * driver model is not inited or the SPI flash is not found. * * @type: Type of MRC data to use - * @devp: Returns pointer to the SPI flash device + * @devp: Returns pointer to the SPI flash device, if found * @entry: Position and size of MRC cache in SPI flash * @return 0 if success, -ENOENT if SPI flash node does not exist in the * device tree, -EPERM if MRC region subnode does not exist in the device diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c index 21c71e036e..f181e8100c 100644 --- a/arch/x86/lib/mrccache.c +++ b/arch/x86/lib/mrccache.c @@ -233,6 +233,7 @@ int mrccache_get_region(enum mrc_type_t type, struct udevice **devp, ulong map_base; uint map_size; uint offset; + ofnode node; u32 reg[2]; int ret; @@ -242,23 +243,36 @@ int mrccache_get_region(enum mrc_type_t type, struct udevice **devp, * memory map cannot be read. */ ret = uclass_find_first_device(UCLASS_SPI_FLASH, &dev); - if (!ret && !dev) + if (ret || !dev) { + /* + * Fall back to searching the device tree since driver model + * may not be ready yet (e.g. with FSPv1) + */ + node = ofnode_by_compatible(ofnode_null(), "jedec,spi-nor"); + if (!ofnode_valid(node)) + return log_msg_ret("Cannot find SPI flash\n", -ENOENT); ret = -ENODEV; - if (ret) - return log_msg_ret("Cannot find SPI flash\n", ret); - ret = dm_spi_get_mmap(dev, &map_base, &map_size, &offset); - if (!ret) { - entry->base = map_base; } else { - ret = dev_read_u32_array(dev, "memory-map", reg, 2); + ret = dm_spi_get_mmap(dev, &map_base, &map_size, &offset); + if (!ret) + entry->base = map_base; + node = dev_ofnode(dev); + } + + /* + * At this point we have entry->base if ret == 0. If not, then we have + * the node and can look for memory-map + */ + if (ret) { + ret = ofnode_read_u32_array(node, "memory-map", reg, 2); if (ret) return log_msg_ret("Cannot find memory map\n", ret); entry->base = reg[0]; } /* Find the place where we put the MRC cache */ - mrc_node = dev_read_subnode(dev, type == MRC_TYPE_NORMAL ? - "rw-mrc-cache" : "rw-var-mrc-cache"); + mrc_node = ofnode_find_subnode(node, type == MRC_TYPE_NORMAL ? + "rw-mrc-cache" : "rw-var-mrc-cache"); if (!ofnode_valid(mrc_node)) return log_msg_ret("Cannot find node", -EPERM); @@ -271,7 +285,8 @@ int mrccache_get_region(enum mrc_type_t type, struct udevice **devp, if (devp) *devp = dev; debug("MRC cache type %d in '%s', offset %x, len %x, base %x\n", - type, dev->name, entry->offset, entry->length, entry->base); + type, dev ? dev->name : ofnode_get_name(node), entry->offset, + entry->length, entry->base); return 0; } diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c index b6f9a70ba7..cf22fa2d7b 100644 --- a/arch/x86/lib/spl.c +++ b/arch/x86/lib/spl.c @@ -164,8 +164,8 @@ void board_init_f(ulong flags) ret = x86_spl_init(); if (ret) { - debug("Error %d\n", ret); - panic("x86_spl_init fail"); + printf("x86_spl_init: error %d\n", ret); + hang(); } #if IS_ENABLED(CONFIG_TPL) || IS_ENABLED(CONFIG_SYS_COREBOOT) gd->bd = malloc(sizeof(*gd->bd)); diff --git a/board/intel/minnowmax/Kconfig b/board/intel/minnowmax/Kconfig index 543468cab5..82a6ca904e 100644 --- a/board/intel/minnowmax/Kconfig +++ b/board/intel/minnowmax/Kconfig @@ -21,6 +21,9 @@ config BOARD_SPECIFIC_OPTIONS # dummy select INTEL_BAYTRAIL select BOARD_ROMSIZE_KB_8192 select SPI_FLASH_STMICRO + # Enable Winbond so we can use Dediprog em100pro emulator which does + # not support N25Q064 + select SPI_FLASH_WINBOND config PCIE_ECAM_BASE default 0xe0000000 diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index 7405062846..e1336b89c5 100644 --- a/drivers/spi/ich.c +++ b/drivers/spi/ich.c @@ -24,6 +24,7 @@ #include <spl.h> #include <asm/fast_spi.h> #include <asm/io.h> +#include <dm/uclass-internal.h> #include <asm/mtrr.h> #include <linux/bitops.h> #include <linux/delay.h> @@ -614,15 +615,94 @@ static int ich_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) return ret; } +/** + * ich_spi_get_basics() - Get basic information about the ICH device + * + * This works without probing any devices if requested. + * + * @bus: SPI controller to use + * @can_probe: true if this function is allowed to probe the PCH + * @pchp: Returns a pointer to the pch, or NULL if not found + * @ich_versionp: Returns ICH version detected on success + * @mmio_basep: Returns the address of the SPI registers on success + * @return 0 if OK, -EPROTOTYPE if the PCH could not be found, -EAGAIN if + * the function cannot success without probing, possible another error if + * pch_get_spi_base() fails + */ +static int ich_spi_get_basics(struct udevice *bus, bool can_probe, + struct udevice **pchp, + enum ich_version *ich_versionp, ulong *mmio_basep) +{ + struct udevice *pch = NULL; + int ret = 0; + + /* Find a PCH if there is one */ + if (can_probe) { + pch = dev_get_parent(bus); + if (device_get_uclass_id(pch) != UCLASS_PCH) { + uclass_first_device(UCLASS_PCH, &pch); + if (!pch) + return log_msg_ret("uclass", -EPROTOTYPE); + } + } + + *ich_versionp = dev_get_driver_data(bus); + if (*ich_versionp == ICHV_APL) + *mmio_basep = dm_pci_read_bar32(bus, 0); + else if (pch) + ret = pch_get_spi_base(pch, mmio_basep); + else + return -EAGAIN; + *pchp = pch; + + return ret; +} + +/** + * ich_get_mmap_bus() - Handle the get_mmap() method for a bus + * + * There are several cases to consider: + * 1. Using of-platdata, in which case we have the BDF and can access the + * registers by reading the BAR + * 2. Not using of-platdata, but still with a SPI controller that is on its own + * PCI PDF. In this case we read the BDF from the parent platdata and again get + * the registers by reading the BAR + * 3. Using a SPI controller that is a child of the PCH, in which case we try + * to find the registers by asking the PCH. This only works if the PCH has + * been probed (which it will be if the bus is probed since parents are + * probed before children), since the PCH may not have a PCI address until + * its parent (the PCI bus itself) has been probed. If you are using this + * method then you should make sure the SPI bus is probed. + * + * The first two cases are useful in early init. The last one is more useful + * afterwards. + */ static int ich_get_mmap_bus(struct udevice *bus, ulong *map_basep, uint *map_sizep, uint *offsetp) { pci_dev_t spi_bdf; - #if !CONFIG_IS_ENABLED(OF_PLATDATA) - struct pci_child_platdata *pplat = dev_get_parent_platdata(bus); + if (device_is_on_pci_bus(bus)) { + struct pci_child_platdata *pplat; + + pplat = dev_get_parent_platdata(bus); + spi_bdf = pplat->devfn; + } else { + enum ich_version ich_version; + struct fast_spi_regs *regs; + struct udevice *pch; + ulong mmio_base; + int ret; - spi_bdf = pplat->devfn; + ret = ich_spi_get_basics(bus, device_active(bus), &pch, + &ich_version, &mmio_base); + if (ret) + return log_msg_ret("basics", ret); + regs = (struct fast_spi_regs *)mmio_base; + + return fast_spi_get_bios_mmap_regs(regs, map_basep, map_sizep, + offsetp); + } #else struct ich_spi_platdata *plat = dev_get_platdata(bus); @@ -866,23 +946,16 @@ static int ich_spi_child_pre_probe(struct udevice *dev) static int ich_spi_ofdata_to_platdata(struct udevice *dev) { struct ich_spi_platdata *plat = dev_get_platdata(dev); + int ret; #if !CONFIG_IS_ENABLED(OF_PLATDATA) struct ich_spi_priv *priv = dev_get_priv(dev); - /* Find a PCH if there is one */ - uclass_first_device(UCLASS_PCH, &priv->pch); - if (!priv->pch) - priv->pch = dev_get_parent(dev); - - plat->ich_version = dev_get_driver_data(dev); + ret = ich_spi_get_basics(dev, true, &priv->pch, &plat->ich_version, + &plat->mmio_base); + if (ret) + return log_msg_ret("basics", ret); plat->lockdown = dev_read_bool(dev, "intel,spi-lock-down"); - if (plat->ich_version == ICHV_APL) { - plat->mmio_base = dm_pci_read_bar32(dev, 0); - } else { - /* SBASE is similar */ - pch_get_spi_base(priv->pch, &plat->mmio_base); - } /* * Use an int so that the property is present in of-platdata even * when false. |