1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) ASPEED Technology Inc. 4 */ 5 6 #include <linux/bitfield.h> 7 #include <common.h> 8 #include <clk.h> 9 #include <dm.h> 10 #include <errno.h> 11 #include <reset.h> 12 #include <fdtdec.h> 13 #include <asm/io.h> 14 #include "dp_mcu_firmware.h" 15 16 #define MCU_CTRL 0x180100e0 17 #define MCU_CTRL_AHBS_IMEM_EN BIT(0) 18 #define MCU_CTRL_AHBS_SW_RST BIT(4) 19 #define MCU_CTRL_AHBM_SW_RST BIT(8) 20 #define MCU_CTRL_CORE_SW_RST BIT(12) 21 #define MCU_CTRL_DMEM_SHUT_DOWN BIT(16) 22 #define MCU_CTRL_DMEM_SLEEP BIT(17) 23 #define MCU_CTRL_DMEM_CLK_OFF BIT(18) 24 #define MCU_CTRL_IMEM_SHUT_DOWN BIT(20) 25 #define MCU_CTRL_IMEM_SLEEP BIT(21) 26 #define MCU_CTRL_IMEM_CLK_OFF BIT(22) 27 #define MCU_CTRL_IMEM_SEL BIT(24) 28 #define MCU_CTRL_CONFIG BIT(28) 29 30 #define MCU_INTR_CTRL 0x180100e8 31 #define MCU_INTR_CTRL_CLR GENMASK(7, 0) 32 #define MCU_INTR_CTRL_MASK GENMASK(15, 8) 33 #define MCU_INTR_CTRL_EN GENMASK(23, 16) 34 35 #define MCU_IMEM_START 0x18020000 36 37 struct aspeed_dp_priv { 38 void *ctrl_base; 39 }; 40 41 static int aspeed_dp_probe(struct udevice *dev) 42 { 43 struct aspeed_dp_priv *dp = dev_get_priv(dev); 44 struct reset_ctl dp_reset_ctl, dpmcu_reset_ctrl; 45 int i, ret = 0, len; 46 const u32 *cell; 47 u32 tmp, mcu_ctrl; 48 49 /* Get the controller base address */ 50 dp->ctrl_base = (void *)devfdt_get_addr_index(dev, 0); 51 52 debug("%s(dev=%p) \n", __func__, dev); 53 54 ret = reset_get_by_index(dev, 0, &dp_reset_ctl); 55 if (ret) { 56 printf("%s(): Failed to get dp reset signal\n", __func__); 57 return ret; 58 } 59 60 ret = reset_get_by_index(dev, 1, &dpmcu_reset_ctrl); 61 if (ret) { 62 printf("%s(): Failed to get dp mcu reset signal\n", __func__); 63 return ret; 64 } 65 66 /* release reset for DPTX and DPMCU */ 67 reset_assert(&dp_reset_ctl); 68 reset_assert(&dpmcu_reset_ctrl); 69 reset_deassert(&dp_reset_ctl); 70 reset_deassert(&dpmcu_reset_ctrl); 71 72 /* select HOST or BMC as display control master 73 enable or disable sending EDID to Host */ 74 writel(readl(dp->ctrl_base + 0xB8) & ~(BIT(24) | BIT(28)), dp->ctrl_base + 0xB8); 75 76 /* DPMCU */ 77 /* clear display format and enable region */ 78 writel(0, 0x18000de0); 79 80 /* load DPMCU firmware to internal instruction memory */ 81 mcu_ctrl = MCU_CTRL_CONFIG | MCU_CTRL_IMEM_CLK_OFF | MCU_CTRL_IMEM_SHUT_DOWN | 82 MCU_CTRL_DMEM_CLK_OFF | MCU_CTRL_DMEM_SHUT_DOWN | MCU_CTRL_AHBS_SW_RST; 83 writel(mcu_ctrl, MCU_CTRL); 84 85 mcu_ctrl &= ~(MCU_CTRL_IMEM_SHUT_DOWN | MCU_CTRL_DMEM_SHUT_DOWN); 86 writel(mcu_ctrl, MCU_CTRL); 87 88 mcu_ctrl &= ~(MCU_CTRL_IMEM_CLK_OFF | MCU_CTRL_DMEM_CLK_OFF); 89 writel(mcu_ctrl, MCU_CTRL); 90 91 mcu_ctrl |= MCU_CTRL_AHBS_IMEM_EN; 92 writel(mcu_ctrl, MCU_CTRL); 93 94 for (i = 0; i < ARRAY_SIZE(firmware_ast2600_dp); i++) 95 writel(firmware_ast2600_dp[i], MCU_IMEM_START + (i * 4)); 96 97 // update configs to dmem for re-driver 98 writel(0x0000dead, 0x18000e00); // mark re-driver cfg not ready 99 cell = dev_read_prop(dev, "eq-table", &len); 100 if (cell) { 101 for (i = 0; i < len / sizeof(u32); ++i) 102 writel(fdt32_to_cpu(cell[i]), 0x18000e04 + i * 4); 103 } else { 104 debug("%s(): Failed to get eq-table for re-driver\n", __func__); 105 goto ERR_DTS; 106 } 107 108 tmp = dev_read_s32_default(dev, "i2c-base-addr", -1); 109 if (tmp == -1) { 110 debug("%s(): Failed to get i2c port's base address\n", __func__); 111 goto ERR_DTS; 112 } 113 writel(tmp, 0x18000e28); 114 115 tmp = dev_read_s32_default(dev, "i2c-buf-addr", -1); 116 if (tmp == -1) { 117 debug("%s(): Failed to get i2c port's buf address\n", __func__); 118 goto ERR_DTS; 119 } 120 writel(tmp, 0x18000e2c); 121 122 tmp = dev_read_s32_default(dev, "dev-addr", -1); 123 if (tmp == -1) 124 tmp = 0x70; 125 writel(tmp, 0x18000e30); 126 writel(0x0000cafe, 0x18000e00); // mark re-driver cfg ready 127 128 ERR_DTS: 129 /* release DPMCU internal reset */ 130 mcu_ctrl &= ~MCU_CTRL_AHBS_IMEM_EN; 131 writel(mcu_ctrl, MCU_CTRL); 132 mcu_ctrl |= MCU_CTRL_CORE_SW_RST | MCU_CTRL_AHBM_SW_RST; 133 writel(mcu_ctrl, MCU_CTRL); 134 //disable dp interrupt 135 writel(FIELD_PREP(MCU_INTR_CTRL_EN, 0xff), MCU_INTR_CTRL); 136 //set vga ASTDP with DPMCU FW handling scratch 137 writel(readl(0x1e6e2100) | (0x7 << 9), 0x1e6e2100); 138 139 return 0; 140 } 141 142 static int dp_aspeed_ofdata_to_platdata(struct udevice *dev) 143 { 144 struct aspeed_dp_priv *dp = dev_get_priv(dev); 145 146 /* Get the controller base address */ 147 dp->ctrl_base = (void *)devfdt_get_addr_index(dev, 0); 148 149 return 0; 150 } 151 152 static const struct udevice_id aspeed_dp_ids[] = { 153 { .compatible = "aspeed,ast2600-displayport" }, 154 { } 155 }; 156 157 U_BOOT_DRIVER(aspeed_dp) = { 158 .name = "aspeed_dp", 159 .id = UCLASS_MISC, 160 .of_match = aspeed_dp_ids, 161 .probe = aspeed_dp_probe, 162 .ofdata_to_platdata = dp_aspeed_ofdata_to_platdata, 163 .priv_auto_alloc_size = sizeof(struct aspeed_dp_priv), 164 }; 165