core.c 12.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
/*
 * core.c - ChipIdea USB IP core family device controller
 *
 * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
 *
 * Author: David Lopo
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

/*
 * Description: ChipIdea USB IP core family device controller
 *
 * This driver is composed of several blocks:
 * - HW:     hardware interface
 * - DBG:    debug facilities (optional)
 * - UTIL:   utilities
 * - ISR:    interrupts handling
 * - ENDPT:  endpoint operations (Gadget API)
 * - GADGET: gadget operations (Gadget API)
 * - BUS:    bus glue code, bus abstraction layer
 *
 * Compile Options
 * - CONFIG_USB_GADGET_DEBUG_FILES: enable debug facilities
 * - STALL_IN:  non-empty bulk-in pipes cannot be halted
 *              if defined mass storage compliance succeeds but with warnings
 *              => case 4: Hi >  Dn
 *              => case 5: Hi >  Di
 *              => case 8: Hi <> Do
 *              if undefined usbtest 13 fails
 * - TRACE:     enable function tracing (depends on DEBUG)
 *
 * Main Features
 * - Chapter 9 & Mass Storage Compliance with Gadget File Storage
 * - Chapter 9 Compliance with Gadget Zero (STALL_IN undefined)
 * - Normal & LPM support
 *
 * USBTEST Report
 * - OK: 0-12, 13 (STALL_IN defined) & 14
 * - Not Supported: 15 & 16 (ISO)
 *
 * TODO List
 * - OTG
 * - Isochronous & Interrupt Traffic
 * - Handle requests which spawns into several TDs
 * - GET_STATUS(device) - always reports 0
 * - Gadget API (majority of optional features)
 * - Suspend & Remote Wakeup
 */
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/module.h>
57
#include <linux/idr.h>
58 59 60 61 62 63 64 65 66 67 68 69 70
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
#include <linux/usb/chipidea.h>

#include "ci.h"
#include "udc.h"
#include "bits.h"
71
#include "host.h"
72 73
#include "debug.h"

74
/* Controller register map */
75 76 77 78 79 80 81 82 83 84 85 86
static uintptr_t ci_regs_nolpm[] = {
	[CAP_CAPLENGTH]		= 0x000UL,
	[CAP_HCCPARAMS]		= 0x008UL,
	[CAP_DCCPARAMS]		= 0x024UL,
	[CAP_TESTMODE]		= 0x038UL,
	[OP_USBCMD]		= 0x000UL,
	[OP_USBSTS]		= 0x004UL,
	[OP_USBINTR]		= 0x008UL,
	[OP_DEVICEADDR]		= 0x014UL,
	[OP_ENDPTLISTADDR]	= 0x018UL,
	[OP_PORTSC]		= 0x044UL,
	[OP_DEVLC]		= 0x084UL,
87
	[OP_OTGSC]		= 0x064UL,
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
	[OP_USBMODE]		= 0x068UL,
	[OP_ENDPTSETUPSTAT]	= 0x06CUL,
	[OP_ENDPTPRIME]		= 0x070UL,
	[OP_ENDPTFLUSH]		= 0x074UL,
	[OP_ENDPTSTAT]		= 0x078UL,
	[OP_ENDPTCOMPLETE]	= 0x07CUL,
	[OP_ENDPTCTRL]		= 0x080UL,
};

static uintptr_t ci_regs_lpm[] = {
	[CAP_CAPLENGTH]		= 0x000UL,
	[CAP_HCCPARAMS]		= 0x008UL,
	[CAP_DCCPARAMS]		= 0x024UL,
	[CAP_TESTMODE]		= 0x0FCUL,
	[OP_USBCMD]		= 0x000UL,
	[OP_USBSTS]		= 0x004UL,
	[OP_USBINTR]		= 0x008UL,
	[OP_DEVICEADDR]		= 0x014UL,
	[OP_ENDPTLISTADDR]	= 0x018UL,
	[OP_PORTSC]		= 0x044UL,
	[OP_DEVLC]		= 0x084UL,
109
	[OP_OTGSC]		= 0x0C4UL,
110 111 112 113 114 115 116 117 118
	[OP_USBMODE]		= 0x0C8UL,
	[OP_ENDPTSETUPSTAT]	= 0x0D8UL,
	[OP_ENDPTPRIME]		= 0x0DCUL,
	[OP_ENDPTFLUSH]		= 0x0E0UL,
	[OP_ENDPTSTAT]		= 0x0E4UL,
	[OP_ENDPTCOMPLETE]	= 0x0E8UL,
	[OP_ENDPTCTRL]		= 0x0ECUL,
};

119
static int hw_alloc_regmap(struct ci13xxx *ci, bool is_lpm)
120 121 122
{
	int i;

123
	kfree(ci->hw_bank.regmap);
124

125 126 127
	ci->hw_bank.regmap = kzalloc((OP_LAST + 1) * sizeof(void *),
				     GFP_KERNEL);
	if (!ci->hw_bank.regmap)
128 129 130
		return -ENOMEM;

	for (i = 0; i < OP_ENDPTCTRL; i++)
131 132
		ci->hw_bank.regmap[i] =
			(i <= CAP_LAST ? ci->hw_bank.cap : ci->hw_bank.op) +
133 134 135
			(is_lpm ? ci_regs_lpm[i] : ci_regs_nolpm[i]);

	for (; i <= OP_LAST; i++)
136
		ci->hw_bank.regmap[i] = ci->hw_bank.op +
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
			4 * (i - OP_ENDPTCTRL) +
			(is_lpm
			 ? ci_regs_lpm[OP_ENDPTCTRL]
			 : ci_regs_nolpm[OP_ENDPTCTRL]);

	return 0;
}

/**
 * hw_port_test_set: writes port test mode (execute without interruption)
 * @mode: new value
 *
 * This function returns an error code
 */
int hw_port_test_set(struct ci13xxx *ci, u8 mode)
{
	const u8 TEST_MODE_MAX = 7;

	if (mode > TEST_MODE_MAX)
		return -EINVAL;

	hw_write(ci, OP_PORTSC, PORTSC_PTC, mode << ffs_nr(PORTSC_PTC));
	return 0;
}

/**
 * hw_port_test_get: reads port test mode value
 *
 * This function returns port test mode value
 */
u8 hw_port_test_get(struct ci13xxx *ci)
{
	return hw_read(ci, OP_PORTSC, PORTSC_PTC) >> ffs_nr(PORTSC_PTC);
}

172
static int hw_device_init(struct ci13xxx *ci, void __iomem *base)
173 174 175 176
{
	u32 reg;

	/* bank is a module variable */
177
	ci->hw_bank.abs = base;
178

179
	ci->hw_bank.cap = ci->hw_bank.abs;
180
	ci->hw_bank.cap += ci->platdata->capoffset;
181
	ci->hw_bank.op = ci->hw_bank.cap + ioread8(ci->hw_bank.cap);
182

183 184
	hw_alloc_regmap(ci, false);
	reg = hw_read(ci, CAP_HCCPARAMS, HCCPARAMS_LEN) >>
185
		ffs_nr(HCCPARAMS_LEN);
186 187 188 189 190
	ci->hw_bank.lpm  = reg;
	hw_alloc_regmap(ci, !!reg);
	ci->hw_bank.size = ci->hw_bank.op - ci->hw_bank.abs;
	ci->hw_bank.size += OP_LAST;
	ci->hw_bank.size /= sizeof(u32);
191

192
	reg = hw_read(ci, CAP_DCCPARAMS, DCCPARAMS_DEN) >>
193
		ffs_nr(DCCPARAMS_DEN);
194
	ci->hw_ep_max = reg * 2;   /* cache hw ENDPT_MAX */
195

196
	if (ci->hw_ep_max > ENDPT_MAX)
197 198
		return -ENODEV;

199 200
	dev_dbg(ci->dev, "ChipIdea HDRC found, lpm: %d; cap: %p op: %p\n",
		ci->hw_bank.lpm, ci->hw_bank.cap, ci->hw_bank.op);
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216

	/* setup lock mode ? */

	/* ENDPTSETUPSTAT is '0' by default */

	/* HCSPARAMS.bf.ppc SHOULD BE zero for device */

	return 0;
}

/**
 * hw_device_reset: resets chip (execute without interruption)
 * @ci: the controller
  *
 * This function returns an error code
 */
217
int hw_device_reset(struct ci13xxx *ci, u32 mode)
218 219 220 221 222 223 224 225 226 227
{
	/* should flush & stop before reset */
	hw_write(ci, OP_ENDPTFLUSH, ~0, ~0);
	hw_write(ci, OP_USBCMD, USBCMD_RS, 0);

	hw_write(ci, OP_USBCMD, USBCMD_RST, USBCMD_RST);
	while (hw_read(ci, OP_USBCMD, USBCMD_RST))
		udelay(10);		/* not RTOS friendly */


228 229
	if (ci->platdata->notify_event)
		ci->platdata->notify_event(ci,
230 231
			CI13XXX_CONTROLLER_RESET_EVENT);

232
	if (ci->platdata->flags & CI13XXX_DISABLE_STREAMING)
233
		hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
234 235 236

	/* USBMODE should be configured step by step */
	hw_write(ci, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
237
	hw_write(ci, OP_USBMODE, USBMODE_CM, mode);
238 239 240
	/* HW >= 2.3 */
	hw_write(ci, OP_USBMODE, USBMODE_SLOM, USBMODE_SLOM);

241 242
	if (hw_read(ci, OP_USBMODE, USBMODE_CM) != mode) {
		pr_err("cannot enter in %s mode", ci_role(ci)->name);
243 244 245 246 247 248 249
		pr_err("lpm = %i", ci->hw_bank.lpm);
		return -ENODEV;
	}

	return 0;
}

250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
/**
 * ci_otg_role - pick role based on ID pin state
 * @ci: the controller
 */
static enum ci_role ci_otg_role(struct ci13xxx *ci)
{
	u32 sts = hw_read(ci, OP_OTGSC, ~0);
	enum ci_role role = sts & OTGSC_ID
		? CI_ROLE_GADGET
		: CI_ROLE_HOST;

	return role;
}

/**
 * ci_role_work - perform role changing based on ID pin
 * @work: work struct
 */
static void ci_role_work(struct work_struct *work)
{
	struct ci13xxx *ci = container_of(work, struct ci13xxx, work);
	enum ci_role role = ci_otg_role(ci);

	if (role != ci->role) {
		dev_dbg(ci->dev, "switching from %s to %s\n",
			ci_role(ci)->name, ci->roles[role]->name);

		ci_role_stop(ci);
		ci_role_start(ci, role);
279
		enable_irq(ci->irq);
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
	}
}

static ssize_t show_role(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
	struct ci13xxx *ci = dev_get_drvdata(dev);

	return sprintf(buf, "%s\n", ci_role(ci)->name);
}

static ssize_t store_role(struct device *dev, struct device_attribute *attr,
			  const char *buf, size_t count)
{
	struct ci13xxx *ci = dev_get_drvdata(dev);
	enum ci_role role;
	int ret;

	for (role = CI_ROLE_HOST; role < CI_ROLE_END; role++)
		if (ci->roles[role] && !strcmp(buf, ci->roles[role]->name))
			break;

	if (role == CI_ROLE_END || role == ci->role)
		return -EINVAL;

	ci_role_stop(ci);
	ret = ci_role_start(ci, role);
	if (ret)
		return ret;

	return count;
}

static DEVICE_ATTR(role, S_IRUSR | S_IWUSR, show_role, store_role);

static irqreturn_t ci_irq(int irq, void *data)
{
	struct ci13xxx *ci = data;
	irqreturn_t ret = IRQ_NONE;
319
	u32 otgsc = 0;
320

321 322
	if (ci->is_otg)
		otgsc = hw_read(ci, OP_OTGSC, ~0);
323

324 325 326 327 328 329 330 331
	if (ci->role != CI_ROLE_END)
		ret = ci_role(ci)->irq(ci);

	if (ci->is_otg && (otgsc & OTGSC_IDIS)) {
		hw_write(ci, OP_OTGSC, OTGSC_IDIS, OTGSC_IDIS);
		disable_irq_nosync(ci->irq);
		queue_work(ci->wq, &ci->work);
		ret = IRQ_HANDLED;
332 333
	}

334
	return ret;
335 336
}

337 338
static DEFINE_IDA(ci_ida);

339 340 341 342 343
struct platform_device *ci13xxx_add_device(struct device *dev,
			struct resource *res, int nres,
			struct ci13xxx_platform_data *platdata)
{
	struct platform_device *pdev;
344
	int id, ret;
345

346 347 348 349 350 351 352 353 354
	id = ida_simple_get(&ci_ida, 0, 0, GFP_KERNEL);
	if (id < 0)
		return ERR_PTR(id);

	pdev = platform_device_alloc("ci_hdrc", id);
	if (!pdev) {
		ret = -ENOMEM;
		goto put_id;
	}
355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376

	pdev->dev.parent = dev;
	pdev->dev.dma_mask = dev->dma_mask;
	pdev->dev.dma_parms = dev->dma_parms;
	dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);

	ret = platform_device_add_resources(pdev, res, nres);
	if (ret)
		goto err;

	ret = platform_device_add_data(pdev, platdata, sizeof(*platdata));
	if (ret)
		goto err;

	ret = platform_device_add(pdev);
	if (ret)
		goto err;

	return pdev;

err:
	platform_device_put(pdev);
377 378
put_id:
	ida_simple_remove(&ci_ida, id);
379 380 381 382 383 384
	return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(ci13xxx_add_device);

void ci13xxx_remove_device(struct platform_device *pdev)
{
385
	int id = pdev->id;
386
	platform_device_unregister(pdev);
387
	ida_simple_remove(&ci_ida, id);
388 389 390
}
EXPORT_SYMBOL_GPL(ci13xxx_remove_device);

B
Bill Pemberton 已提交
391
static int ci_hdrc_probe(struct platform_device *pdev)
392 393
{
	struct device	*dev = &pdev->dev;
394
	struct ci13xxx	*ci;
395 396 397 398
	struct resource	*res;
	void __iomem	*base;
	int		ret;

399
	if (!dev->platform_data) {
400 401 402 403 404 405 406 407 408 409 410
		dev_err(dev, "platform data missing\n");
		return -ENODEV;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(dev, "missing resource\n");
		return -ENODEV;
	}

	base = devm_request_and_ioremap(dev, res);
411
	if (!base) {
412 413 414 415
		dev_err(dev, "can't request and ioremap resource\n");
		return -ENOMEM;
	}

416 417 418 419 420 421 422
	ci = devm_kzalloc(dev, sizeof(*ci), GFP_KERNEL);
	if (!ci) {
		dev_err(dev, "can't allocate device\n");
		return -ENOMEM;
	}

	ci->dev = dev;
423
	ci->platdata = dev->platform_data;
424 425 426 427
	if (ci->platdata->phy)
		ci->transceiver = ci->platdata->phy;
	else
		ci->global_phy = true;
428 429 430 431 432 433

	ret = hw_device_init(ci, base);
	if (ret < 0) {
		dev_err(dev, "can't initialize hardware\n");
		return -ENODEV;
	}
434

435 436
	ci->hw_bank.phys = res->start;

437 438
	ci->irq = platform_get_irq(pdev, 0);
	if (ci->irq < 0) {
439
		dev_err(dev, "missing IRQ\n");
440 441 442 443 444 445 446 447 448 449 450
		return -ENODEV;
	}

	INIT_WORK(&ci->work, ci_role_work);
	ci->wq = create_singlethread_workqueue("ci_otg");
	if (!ci->wq) {
		dev_err(dev, "can't create workqueue\n");
		return -ENODEV;
	}

	/* initialize role(s) before the interrupt is requested */
451 452 453 454
	ret = ci_hdrc_host_init(ci);
	if (ret)
		dev_info(dev, "doesn't support host\n");

455 456 457 458 459 460 461 462 463 464 465 466
	ret = ci_hdrc_gadget_init(ci);
	if (ret)
		dev_info(dev, "doesn't support gadget\n");

	if (!ci->roles[CI_ROLE_HOST] && !ci->roles[CI_ROLE_GADGET]) {
		dev_err(dev, "no supported roles\n");
		ret = -ENODEV;
		goto rm_wq;
	}

	if (ci->roles[CI_ROLE_HOST] && ci->roles[CI_ROLE_GADGET]) {
		ci->is_otg = true;
467 468
		/* ID pin needs 1ms debouce time, we delay 2ms for safe */
		mdelay(2);
469 470 471 472 473 474 475 476 477 478
		ci->role = ci_otg_role(ci);
	} else {
		ci->role = ci->roles[CI_ROLE_HOST]
			? CI_ROLE_HOST
			: CI_ROLE_GADGET;
	}

	ret = ci_role_start(ci, ci->role);
	if (ret) {
		dev_err(dev, "can't start %s role\n", ci_role(ci)->name);
479
		ret = -ENODEV;
480
		goto rm_wq;
481 482
	}

483
	platform_set_drvdata(pdev, ci);
484
	ret = request_irq(ci->irq, ci_irq, IRQF_SHARED, ci->platdata->name,
485 486 487
			  ci);
	if (ret)
		goto stop;
488

489
	ret = device_create_file(dev, &dev_attr_role);
490
	if (ret)
491 492 493 494 495 496 497 498 499 500 501 502 503 504
		goto rm_attr;

	if (ci->is_otg)
		hw_write(ci, OP_OTGSC, OTGSC_IDIE, OTGSC_IDIE);

	return ret;

rm_attr:
	device_remove_file(dev, &dev_attr_role);
stop:
	ci_role_stop(ci);
rm_wq:
	flush_workqueue(ci->wq);
	destroy_workqueue(ci->wq);
505 506 507 508

	return ret;
}

B
Bill Pemberton 已提交
509
static int ci_hdrc_remove(struct platform_device *pdev)
510
{
511
	struct ci13xxx *ci = platform_get_drvdata(pdev);
512

513 514 515 516 517
	flush_workqueue(ci->wq);
	destroy_workqueue(ci->wq);
	device_remove_file(ci->dev, &dev_attr_role);
	free_irq(ci->irq, ci);
	ci_role_stop(ci);
518 519 520 521

	return 0;
}

522 523
static struct platform_driver ci_hdrc_driver = {
	.probe	= ci_hdrc_probe,
B
Bill Pemberton 已提交
524
	.remove	= ci_hdrc_remove,
525
	.driver	= {
526
		.name	= "ci_hdrc",
527 528 529
	},
};

530
module_platform_driver(ci_hdrc_driver);
531

532
MODULE_ALIAS("platform:ci_hdrc");
533 534 535
MODULE_ALIAS("platform:ci13xxx");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("David Lopo <dlopo@chipidea.mips.com>");
536
MODULE_DESCRIPTION("ChipIdea HDRC Driver");