Angel Pons | 3bd1e3d | 2020-04-05 15:47:17 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Subrata Banik | cb771a2 | 2017-11-28 16:26:08 +0530 | [diff] [blame] | 2 | |
Nico Huber | 1a65017 | 2018-12-16 02:39:28 +0100 | [diff] [blame] | 3 | #include <commonlib/helpers.h> |
Nico Huber | 826094f | 2020-04-26 19:24:00 +0200 | [diff] [blame] | 4 | #include <device/mmio.h> |
Paul Menzel | 270a323 | 2020-07-25 10:49:44 +0200 | [diff] [blame] | 5 | #include <device/pci_rom.h> |
Nico Huber | 1a65017 | 2018-12-16 02:39:28 +0100 | [diff] [blame] | 6 | #include <device/resource.h> |
Matt DeVillier | ddb4cf0 | 2020-03-27 14:13:07 -0500 | [diff] [blame] | 7 | #include <drivers/intel/gma/i915.h> |
Subrata Banik | cb771a2 | 2017-11-28 16:26:08 +0530 | [diff] [blame] | 8 | #include <drivers/intel/gma/i915_reg.h> |
| 9 | #include <intelblocks/graphics.h> |
Subrata Banik | cb771a2 | 2017-11-28 16:26:08 +0530 | [diff] [blame] | 10 | #include <soc/ramstage.h> |
Paul Menzel | 270a323 | 2020-07-25 10:49:44 +0200 | [diff] [blame] | 11 | #include <soc/systemagent.h> |
Elyes HAOUAS | 27d02d8 | 2019-05-15 21:11:39 +0200 | [diff] [blame] | 12 | #include <types.h> |
Subrata Banik | cb771a2 | 2017-11-28 16:26:08 +0530 | [diff] [blame] | 13 | |
Matt DeVillier | 395ab9d | 2020-12-23 17:30:27 -0600 | [diff] [blame] | 14 | void graphics_soc_panel_init(struct device *dev) |
Nico Huber | 1a65017 | 2018-12-16 02:39:28 +0100 | [diff] [blame] | 15 | { |
Kyösti Mälkki | 8950cfb | 2019-07-13 22:16:25 +0300 | [diff] [blame] | 16 | struct soc_intel_skylake_config *conf = config_of(dev); |
Michael Niewöhner | 97e21d3 | 2020-12-28 00:49:33 +0100 | [diff] [blame] | 17 | const struct i915_gpu_panel_config *panel_cfg; |
Nico Huber | 1a65017 | 2018-12-16 02:39:28 +0100 | [diff] [blame] | 18 | struct resource *mmio_res; |
| 19 | uint8_t *base; |
| 20 | u32 reg32; |
| 21 | |
| 22 | if (!conf) |
| 23 | return; |
| 24 | |
Michael Niewöhner | 97e21d3 | 2020-12-28 00:49:33 +0100 | [diff] [blame] | 25 | panel_cfg = &conf->panel_cfg; |
| 26 | |
Nico Huber | 1a65017 | 2018-12-16 02:39:28 +0100 | [diff] [blame] | 27 | mmio_res = find_resource(dev, PCI_BASE_ADDRESS_0); |
| 28 | if (!mmio_res || !mmio_res->base) |
| 29 | return; |
| 30 | base = (void *)(uintptr_t)mmio_res->base; |
| 31 | |
Michael Niewöhner | 97e21d3 | 2020-12-28 00:49:33 +0100 | [diff] [blame] | 32 | reg32 = ((panel_cfg->up_delay_ms * 10) & 0x1fff) << 16; |
| 33 | reg32 |= (panel_cfg->backlight_on_delay_ms * 10) & 0x1fff; |
Nico Huber | 1a65017 | 2018-12-16 02:39:28 +0100 | [diff] [blame] | 34 | write32(base + PCH_PP_ON_DELAYS, reg32); |
| 35 | |
Michael Niewöhner | 97e21d3 | 2020-12-28 00:49:33 +0100 | [diff] [blame] | 36 | reg32 = ((panel_cfg->down_delay_ms * 10) & 0x1fff) << 16; |
| 37 | reg32 |= (panel_cfg->backlight_off_delay_ms * 10) & 0x1fff; |
Nico Huber | 1a65017 | 2018-12-16 02:39:28 +0100 | [diff] [blame] | 38 | write32(base + PCH_PP_OFF_DELAYS, reg32); |
| 39 | |
| 40 | reg32 = read32(base + PCH_PP_DIVISOR); |
| 41 | reg32 &= ~0x1f; |
Michael Niewöhner | 97e21d3 | 2020-12-28 00:49:33 +0100 | [diff] [blame] | 42 | reg32 |= (DIV_ROUND_UP(panel_cfg->cycle_delay_ms, 100) + 1) & 0x1f; |
Nico Huber | 1a65017 | 2018-12-16 02:39:28 +0100 | [diff] [blame] | 43 | write32(base + PCH_PP_DIVISOR, reg32); |
| 44 | |
| 45 | /* So far all devices seem to use the PCH PWM function. |
| 46 | The CPU PWM registers are all zero after reset. */ |
Michael Niewöhner | 97e21d3 | 2020-12-28 00:49:33 +0100 | [diff] [blame] | 47 | if (panel_cfg->backlight_pwm_hz) { |
Nico Huber | 1a65017 | 2018-12-16 02:39:28 +0100 | [diff] [blame] | 48 | /* Reference clock is 24MHz. We can choose either a 16 |
| 49 | or a 128 step increment. Use 16 if we would have less |
| 50 | than 100 steps otherwise. */ |
| 51 | const unsigned int hz_limit = 24 * 1000 * 1000 / 128 / 100; |
| 52 | unsigned int pwm_increment, pwm_period; |
| 53 | u32 south_chicken1; |
| 54 | |
| 55 | south_chicken1 = read32(base + SOUTH_CHICKEN1); |
Michael Niewöhner | 97e21d3 | 2020-12-28 00:49:33 +0100 | [diff] [blame] | 56 | if (panel_cfg->backlight_pwm_hz > hz_limit) { |
Nico Huber | 1a65017 | 2018-12-16 02:39:28 +0100 | [diff] [blame] | 57 | pwm_increment = 16; |
| 58 | south_chicken1 &= ~1; |
| 59 | } else { |
| 60 | pwm_increment = 128; |
| 61 | south_chicken1 |= 1; |
| 62 | } |
| 63 | write32(base + SOUTH_CHICKEN1, south_chicken1); |
| 64 | |
Michael Niewöhner | 97e21d3 | 2020-12-28 00:49:33 +0100 | [diff] [blame] | 65 | pwm_period = 24 * 1000 * 1000 / pwm_increment / panel_cfg->backlight_pwm_hz; |
Nico Huber | 1a65017 | 2018-12-16 02:39:28 +0100 | [diff] [blame] | 66 | /* Start with a 50% duty cycle. */ |
Michael Niewöhner | 97e21d3 | 2020-12-28 00:49:33 +0100 | [diff] [blame] | 67 | write32(base + BLC_PWM_PCH_CTL2, pwm_period << 16 | pwm_period / 2); |
Nico Huber | 1a65017 | 2018-12-16 02:39:28 +0100 | [diff] [blame] | 68 | |
| 69 | write32(base + BLC_PWM_PCH_CTL1, |
Michael Niewöhner | 97e21d3 | 2020-12-28 00:49:33 +0100 | [diff] [blame] | 70 | !!panel_cfg->backlight_polarity << 29 | BLM_PCH_PWM_ENABLE); |
Nico Huber | 1a65017 | 2018-12-16 02:39:28 +0100 | [diff] [blame] | 71 | } |
| 72 | } |
| 73 | |
Matt DeVillier | ddb4cf0 | 2020-03-27 14:13:07 -0500 | [diff] [blame] | 74 | const struct i915_gpu_controller_info * |
Furquan Shaikh | ec3dafd | 2020-04-24 21:53:42 -0700 | [diff] [blame] | 75 | intel_igd_get_controller_info(const struct device *device) |
Matt DeVillier | ddb4cf0 | 2020-03-27 14:13:07 -0500 | [diff] [blame] | 76 | { |
| 77 | struct soc_intel_skylake_config *chip = device->chip_info; |
| 78 | return &chip->gfx; |
| 79 | } |
Paul Menzel | 270a323 | 2020-07-25 10:49:44 +0200 | [diff] [blame] | 80 | |
| 81 | /* |
| 82 | * Some VGA option roms are used for several chipsets but they only have one PCI ID in their |
| 83 | * header. If we encounter such an option rom, we need to do the mapping ourselves. |
| 84 | */ |
| 85 | u32 map_oprom_vendev(u32 vendev) |
| 86 | { |
| 87 | u32 new_vendev = vendev; |
| 88 | |
| 89 | switch (vendev) { |
| 90 | case 0x80865916: /* PCI_DEVICE_ID_INTEL_KBL_GT2_SULTM */ |
| 91 | case 0x80865917: /* PCI_DEVICE_ID_INTEL_KBL_GT2_SULTMR */ |
| 92 | new_vendev = SA_IGD_OPROM_VENDEV; |
| 93 | break; |
| 94 | } |
| 95 | |
| 96 | return new_vendev; |
| 97 | } |