1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2015-2018, Intel Corporation. 4 */ 5 6#define pr_fmt(fmt) "aspeed-kcs-bmc: " fmt 7 8#include <linux/atomic.h> 9#include <linux/errno.h> 10#include <linux/interrupt.h> 11#include <linux/io.h> 12#include <linux/mfd/syscon.h> 13#include <linux/module.h> 14#include <linux/of.h> 15#include <linux/of_address.h> 16#include <linux/platform_device.h> 17#include <linux/poll.h> 18#include <linux/regmap.h> 19#include <linux/sched.h> 20#include <linux/slab.h> 21#include <linux/timer.h> 22 23#include "kcs_bmc.h" 24 25 26#define DEVICE_NAME "ast-kcs-bmc" 27 28#define KCS_CHANNEL_MAX 4 29 30/* mapped to lpc-bmc@0 IO space */ 31#define LPC_HICR0 0x000 32#define LPC_HICR0_LPC3E BIT(7) 33#define LPC_HICR0_LPC2E BIT(6) 34#define LPC_HICR0_LPC1E BIT(5) 35#define LPC_HICR2 0x008 36#define LPC_HICR2_IBFIF3 BIT(3) 37#define LPC_HICR2_IBFIF2 BIT(2) 38#define LPC_HICR2_IBFIF1 BIT(1) 39#define LPC_HICR4 0x010 40#define LPC_HICR4_LADR12AS BIT(7) 41#define LPC_HICR4_KCSENBL BIT(2) 42#define LPC_LADR3H 0x014 43#define LPC_LADR3L 0x018 44#define LPC_LADR12H 0x01C 45#define LPC_LADR12L 0x020 46#define LPC_IDR1 0x024 47#define LPC_IDR2 0x028 48#define LPC_IDR3 0x02C 49#define LPC_ODR1 0x030 50#define LPC_ODR2 0x034 51#define LPC_ODR3 0x038 52#define LPC_STR1 0x03C 53#define LPC_STR2 0x040 54#define LPC_STR3 0x044 55 56/* mapped to lpc-host@80 IO space */ 57#define LPC_HICRB 0x080 58#define LPC_HICRB_IBFIF4 BIT(1) 59#define LPC_HICRB_LPC4E BIT(0) 60#define LPC_LADR4 0x090 61#define LPC_IDR4 0x094 62#define LPC_ODR4 0x098 63#define LPC_STR4 0x09C 64 65struct aspeed_kcs_bmc { 66 struct regmap *map; 67}; 68 69 70static u8 aspeed_kcs_inb(struct kcs_bmc *kcs_bmc, u32 reg) 71{ 72 struct aspeed_kcs_bmc *priv = kcs_bmc_priv(kcs_bmc); 73 u32 val = 0; 74 int rc; 75 76 rc = regmap_read(priv->map, reg, &val); 77 WARN(rc != 0, "regmap_read() failed: %d\n", rc); 78 79 return rc == 0 ? (u8) val : 0; 80} 81 82static void aspeed_kcs_outb(struct kcs_bmc *kcs_bmc, u32 reg, u8 data) 83{ 84 struct aspeed_kcs_bmc *priv = kcs_bmc_priv(kcs_bmc); 85 int rc; 86 87 rc = regmap_write(priv->map, reg, data); 88 WARN(rc != 0, "regmap_write() failed: %d\n", rc); 89} 90 91 92/* 93 * AST_usrGuide_KCS.pdf 94 * 2. Background: 95 * we note D for Data, and C for Cmd/Status, default rules are 96 * A. KCS1 / KCS2 ( D / C:X / X+4 ) 97 * D / C : CA0h / CA4h 98 * D / C : CA8h / CACh 99 * B. KCS3 ( D / C:XX2h / XX3h ) 100 * D / C : CA2h / CA3h 101 * D / C : CB2h / CB3h 102 * C. KCS4 103 * D / C : CA4h / CA5h 104 */ 105static void aspeed_kcs_set_address(struct kcs_bmc *kcs_bmc, u16 addr) 106{ 107 struct aspeed_kcs_bmc *priv = kcs_bmc_priv(kcs_bmc); 108 109 switch (kcs_bmc->channel) { 110 case 1: 111 regmap_update_bits(priv->map, LPC_HICR4, 112 LPC_HICR4_LADR12AS, 0); 113 regmap_write(priv->map, LPC_LADR12H, addr >> 8); 114 regmap_write(priv->map, LPC_LADR12L, addr & 0xFF); 115 break; 116 117 case 2: 118 regmap_update_bits(priv->map, LPC_HICR4, 119 LPC_HICR4_LADR12AS, LPC_HICR4_LADR12AS); 120 regmap_write(priv->map, LPC_LADR12H, addr >> 8); 121 regmap_write(priv->map, LPC_LADR12L, addr & 0xFF); 122 break; 123 124 case 3: 125 regmap_write(priv->map, LPC_LADR3H, addr >> 8); 126 regmap_write(priv->map, LPC_LADR3L, addr & 0xFF); 127 break; 128 129 case 4: 130 regmap_write(priv->map, LPC_LADR4, ((addr + 1) << 16) | 131 addr); 132 break; 133 134 default: 135 break; 136 } 137} 138 139static void aspeed_kcs_enable_channel(struct kcs_bmc *kcs_bmc, bool enable) 140{ 141 struct aspeed_kcs_bmc *priv = kcs_bmc_priv(kcs_bmc); 142 143 switch (kcs_bmc->channel) { 144 case 1: 145 if (enable) { 146 regmap_update_bits(priv->map, LPC_HICR2, 147 LPC_HICR2_IBFIF1, LPC_HICR2_IBFIF1); 148 regmap_update_bits(priv->map, LPC_HICR0, 149 LPC_HICR0_LPC1E, LPC_HICR0_LPC1E); 150 } else { 151 regmap_update_bits(priv->map, LPC_HICR0, 152 LPC_HICR0_LPC1E, 0); 153 regmap_update_bits(priv->map, LPC_HICR2, 154 LPC_HICR2_IBFIF1, 0); 155 } 156 break; 157 158 case 2: 159 if (enable) { 160 regmap_update_bits(priv->map, LPC_HICR2, 161 LPC_HICR2_IBFIF2, LPC_HICR2_IBFIF2); 162 regmap_update_bits(priv->map, LPC_HICR0, 163 LPC_HICR0_LPC2E, LPC_HICR0_LPC2E); 164 } else { 165 regmap_update_bits(priv->map, LPC_HICR0, 166 LPC_HICR0_LPC2E, 0); 167 regmap_update_bits(priv->map, LPC_HICR2, 168 LPC_HICR2_IBFIF2, 0); 169 } 170 break; 171 172 case 3: 173 if (enable) { 174 regmap_update_bits(priv->map, LPC_HICR2, 175 LPC_HICR2_IBFIF3, LPC_HICR2_IBFIF3); 176 regmap_update_bits(priv->map, LPC_HICR0, 177 LPC_HICR0_LPC3E, LPC_HICR0_LPC3E); 178 regmap_update_bits(priv->map, LPC_HICR4, 179 LPC_HICR4_KCSENBL, LPC_HICR4_KCSENBL); 180 } else { 181 regmap_update_bits(priv->map, LPC_HICR0, 182 LPC_HICR0_LPC3E, 0); 183 regmap_update_bits(priv->map, LPC_HICR4, 184 LPC_HICR4_KCSENBL, 0); 185 regmap_update_bits(priv->map, LPC_HICR2, 186 LPC_HICR2_IBFIF3, 0); 187 } 188 break; 189 190 case 4: 191 if (enable) 192 regmap_update_bits(priv->map, LPC_HICRB, 193 LPC_HICRB_IBFIF4 | LPC_HICRB_LPC4E, 194 LPC_HICRB_IBFIF4 | LPC_HICRB_LPC4E); 195 else 196 regmap_update_bits(priv->map, LPC_HICRB, 197 LPC_HICRB_IBFIF4 | LPC_HICRB_LPC4E, 198 0); 199 break; 200 201 default: 202 break; 203 } 204} 205 206static irqreturn_t aspeed_kcs_irq(int irq, void *arg) 207{ 208 struct kcs_bmc *kcs_bmc = arg; 209 210 if (!kcs_bmc_handle_event(kcs_bmc)) 211 return IRQ_HANDLED; 212 213 return IRQ_NONE; 214} 215 216static int aspeed_kcs_config_irq(struct kcs_bmc *kcs_bmc, 217 struct platform_device *pdev) 218{ 219 struct device *dev = &pdev->dev; 220 int irq; 221 222 irq = platform_get_irq(pdev, 0); 223 if (irq < 0) 224 return irq; 225 226 return devm_request_irq(dev, irq, aspeed_kcs_irq, IRQF_SHARED, 227 dev_name(dev), kcs_bmc); 228} 229 230static const struct kcs_ioreg ast_kcs_bmc_ioregs[KCS_CHANNEL_MAX] = { 231 { .idr = LPC_IDR1, .odr = LPC_ODR1, .str = LPC_STR1 }, 232 { .idr = LPC_IDR2, .odr = LPC_ODR2, .str = LPC_STR2 }, 233 { .idr = LPC_IDR3, .odr = LPC_ODR3, .str = LPC_STR3 }, 234 { .idr = LPC_IDR4, .odr = LPC_ODR4, .str = LPC_STR4 }, 235}; 236 237static struct kcs_bmc *aspeed_kcs_probe_of_v1(struct platform_device *pdev) 238{ 239 struct aspeed_kcs_bmc *priv; 240 struct device_node *np; 241 struct kcs_bmc *kcs; 242 u32 channel; 243 u32 slave; 244 int rc; 245 246 np = pdev->dev.of_node; 247 248 rc = of_property_read_u32(np, "kcs_chan", &channel); 249 if ((rc != 0) || (channel == 0 || channel > KCS_CHANNEL_MAX)) { 250 dev_err(&pdev->dev, "no valid 'kcs_chan' configured\n"); 251 return ERR_PTR(-EINVAL); 252 } 253 254 kcs = kcs_bmc_alloc(&pdev->dev, sizeof(struct aspeed_kcs_bmc), channel); 255 if (!kcs) 256 return ERR_PTR(-ENOMEM); 257 258 priv = kcs_bmc_priv(kcs); 259 priv->map = syscon_node_to_regmap(pdev->dev.parent->of_node); 260 if (IS_ERR(priv->map)) { 261 dev_err(&pdev->dev, "Couldn't get regmap\n"); 262 return ERR_PTR(-ENODEV); 263 } 264 265 rc = of_property_read_u32(np, "kcs_addr", &slave); 266 if (rc) { 267 dev_err(&pdev->dev, "no valid 'kcs_addr' configured\n"); 268 return ERR_PTR(-EINVAL); 269 } 270 271 kcs->ioreg = ast_kcs_bmc_ioregs[channel - 1]; 272 aspeed_kcs_set_address(kcs, slave); 273 274 return kcs; 275} 276 277static int aspeed_kcs_calculate_channel(const struct kcs_ioreg *regs) 278{ 279 int i; 280 281 for (i = 0; i < ARRAY_SIZE(ast_kcs_bmc_ioregs); i++) { 282 if (!memcmp(&ast_kcs_bmc_ioregs[i], regs, sizeof(*regs))) 283 return i + 1; 284 } 285 286 return -EINVAL; 287} 288 289static struct kcs_bmc *aspeed_kcs_probe_of_v2(struct platform_device *pdev) 290{ 291 struct aspeed_kcs_bmc *priv; 292 struct device_node *np; 293 struct kcs_ioreg ioreg; 294 struct kcs_bmc *kcs; 295 const __be32 *reg; 296 int channel; 297 u32 slave; 298 int rc; 299 300 np = pdev->dev.of_node; 301 302 /* Don't translate addresses, we want offsets for the regmaps */ 303 reg = of_get_address(np, 0, NULL, NULL); 304 if (!reg) 305 return ERR_PTR(-EINVAL); 306 ioreg.idr = be32_to_cpup(reg); 307 308 reg = of_get_address(np, 1, NULL, NULL); 309 if (!reg) 310 return ERR_PTR(-EINVAL); 311 ioreg.odr = be32_to_cpup(reg); 312 313 reg = of_get_address(np, 2, NULL, NULL); 314 if (!reg) 315 return ERR_PTR(-EINVAL); 316 ioreg.str = be32_to_cpup(reg); 317 318 channel = aspeed_kcs_calculate_channel(&ioreg); 319 if (channel < 0) 320 return ERR_PTR(channel); 321 322 kcs = kcs_bmc_alloc(&pdev->dev, sizeof(struct aspeed_kcs_bmc), channel); 323 if (!kcs) 324 return ERR_PTR(-ENOMEM); 325 326 kcs->ioreg = ioreg; 327 328 priv = kcs_bmc_priv(kcs); 329 priv->map = syscon_node_to_regmap(pdev->dev.parent->of_node); 330 if (IS_ERR(priv->map)) { 331 dev_err(&pdev->dev, "Couldn't get regmap\n"); 332 return ERR_PTR(-ENODEV); 333 } 334 335 rc = of_property_read_u32(np, "aspeed,lpc-io-reg", &slave); 336 if (rc) 337 return ERR_PTR(rc); 338 339 aspeed_kcs_set_address(kcs, slave); 340 341 return kcs; 342} 343 344static int aspeed_kcs_probe(struct platform_device *pdev) 345{ 346 struct device *dev = &pdev->dev; 347 struct kcs_bmc *kcs_bmc; 348 struct device_node *np; 349 int rc; 350 351 np = pdev->dev.of_node; 352 if (of_device_is_compatible(np, "aspeed,ast2400-kcs-bmc") || 353 of_device_is_compatible(np, "aspeed,ast2500-kcs-bmc")) 354 kcs_bmc = aspeed_kcs_probe_of_v1(pdev); 355 else if (of_device_is_compatible(np, "aspeed,ast2400-kcs-bmc-v2") || 356 of_device_is_compatible(np, "aspeed,ast2500-kcs-bmc-v2")) 357 kcs_bmc = aspeed_kcs_probe_of_v2(pdev); 358 else 359 return -EINVAL; 360 361 if (IS_ERR(kcs_bmc)) 362 return PTR_ERR(kcs_bmc); 363 364 kcs_bmc->io_inputb = aspeed_kcs_inb; 365 kcs_bmc->io_outputb = aspeed_kcs_outb; 366 367 rc = aspeed_kcs_config_irq(kcs_bmc, pdev); 368 if (rc) 369 return rc; 370 371 dev_set_drvdata(dev, kcs_bmc); 372 373 aspeed_kcs_enable_channel(kcs_bmc, true); 374 375 rc = misc_register(&kcs_bmc->miscdev); 376 if (rc) { 377 dev_err(dev, "Unable to register device\n"); 378 return rc; 379 } 380 381 dev_dbg(&pdev->dev, 382 "Probed KCS device %d (IDR=0x%x, ODR=0x%x, STR=0x%x)\n", 383 kcs_bmc->channel, kcs_bmc->ioreg.idr, kcs_bmc->ioreg.odr, 384 kcs_bmc->ioreg.str); 385 386 return 0; 387} 388 389static int aspeed_kcs_remove(struct platform_device *pdev) 390{ 391 struct kcs_bmc *kcs_bmc = dev_get_drvdata(&pdev->dev); 392 393 misc_deregister(&kcs_bmc->miscdev); 394 395 return 0; 396} 397 398static const struct of_device_id ast_kcs_bmc_match[] = { 399 { .compatible = "aspeed,ast2400-kcs-bmc" }, 400 { .compatible = "aspeed,ast2500-kcs-bmc" }, 401 { .compatible = "aspeed,ast2400-kcs-bmc-v2" }, 402 { .compatible = "aspeed,ast2500-kcs-bmc-v2" }, 403 { } 404}; 405MODULE_DEVICE_TABLE(of, ast_kcs_bmc_match); 406 407static struct platform_driver ast_kcs_bmc_driver = { 408 .driver = { 409 .name = DEVICE_NAME, 410 .of_match_table = ast_kcs_bmc_match, 411 }, 412 .probe = aspeed_kcs_probe, 413 .remove = aspeed_kcs_remove, 414}; 415module_platform_driver(ast_kcs_bmc_driver); 416 417MODULE_LICENSE("GPL v2"); 418MODULE_AUTHOR("Haiyue Wang <haiyue.wang@linux.intel.com>"); 419MODULE_DESCRIPTION("Aspeed device interface to the KCS BMC device"); 420