Maxim & TI serdes 识别流程

市面上汽车上camera大致使用的就两种serdes:美信和TI,这篇文章根据我的理解描述下两种serdes的识别link流程

max96712

ambarella的具体的调用流程可以参考上一篇文章

  • max96712_hw_init
static int max96712_hw_init(struct vin_brg_device *ambrg, u32 chip_id)
{
   
   
	....
	/* check DES ID */
	max96712_read_reg(ambrg, pinfo->i2c_ctrl.addr.des, 0x000D, &dev_id);
	for (i = 0; i < ARRAY_SIZE(id_table); i++) {
   
   
		if (dev_id == id_table[i].id) {
   
   
			brg_info("[%d]deserializer %s, id:0x%x, GMSL%s\n", ambrg->id, id_table[i].name, dev_id,
				(pinfo->link_mode == MAX96712_MODE_GMSL_1) ? "1" :
				((pinfo->link_mode == MAX96712_MODE_GMSL_2_3G) ?  "2(3Gpbs)" : "2(6Gpbs)"));
			break;
		}
	}

	if (test_mode)
		goto HW_INIT_EXIT;

	/* switch deserializer to 3G first if necessary */
	if ((dev_id == DES_96712_ID) && (pinfo->link_mode == MAX96712_MODE_GMSL_2_3G)) {
   
   
		for (i = 0; i < MAX96712_MAX_CHAN_NUM; i++) {
   
   
			/* use load id here because for 3G broken channels, no chance to set to 3G for recovery again */
			if (ambrg->ch_id.load_id & (1U << i)) {
   
   
				addr = (i < 2U) ? 0x0010 : 0x0011;

				max96712_read_reg(ambrg, pinfo->i2c_ctrl.addr.des, addr, &data);
				data &= ~(0x3 << ((i & 0x1) << 2U));
				data |= 0x1 << ((i & 0x1) << 2U);
				max96712_write_reg(ambrg, pinfo->i2c_ctrl.addr.des, addr, data);
			}
		}
	}

	/* turn on poc power source for SER */
	max96712_poc_pwr_rst(ambrg, chip_id);

	...

	/* check SER ID, reset each link */
	for (i = 0; i < MAX96712_MAX_CHAN_NUM; i++) {
   
   
		if (chip_id & (1U << i)) {
   
   
			/* Mask other links except current link */
			max96712_read_reg(ambrg, pinfo->i2c_ctrl.addr.des, 0x0006, &data);
			data &= ~0xF;
			//读取寄存器1dc,1fc,21c,23c,查看对应的video channel locked标志位
			data |= max96712_get_vlocked_chan(ambrg); /* for video locked channel, not to mask because it's streaming */
			data |= 1U << i;
			max96712_write_reg(ambrg, pinfo->i2c_ctrl.addr.des, 0x0006, data);
			/* wait for link stable */
			//查看对应的link是否locked,link A:0x1A, link B:0xA, link C:0xB, link D:0xC
			rval = max96712_wait_lock_status(ambrg, max9295d ? 0x01 : 1U << i, MAX96712_LINK_LOCK_TO);
			if (rval) {
   
   
				brg_error("[%d]serializer link 0x%x fail!\n", ambrg->id, 1U << i);
				broken_id |= 1U << i;
				continue;
			}

			addr = chan2addr(ambrg, 1U << i);

			/* Remap serializer's address */
			//设置对应link的serializer地址
			max96712_write_reg(ambrg, pinfo->i2c_ctrl.addr.ser_def, 0x0000, addr);

			dev_id = 0;
			max96712_read_reg(ambrg, addr, 0x000D, &dev_id);
			for (j = 0; j < ARRAY_SIZE(id_table); j++) {
   
   
				if (dev_id == id_table[j].id) {
   
   
					brg_info("[%d:%d]serializer %s, id:0x%x\n", ambrg->id, 1U << i, id_table[j].name, dev_id);
					break;
				}
			}

			if (dev_id == SER_96717_ID || dev_id == SER_96717F_ID)
				pinfo->is_max96717 = true;
			else if (dev_id == SER_9295D_ID)
				pinfo->is_max9295d = true;

			/* FIXME: just report error here if serializer is not max9295d */
			if (max9295d && !pinfo->is_max9295d)
				brg_error("serializer is not max9295d!\n");

			/* sensor i2c address mapping for each channel */
			//设置sensor地址
			max96712_write_reg(ambrg, addr, 0x0042, pinfo->i2c_ctrl.addr.sen_chan[i]);
			max96712_write_reg(ambrg, addr, 0x0043, ambrg->sensor_ctrl.dev_addr);

			/* sensor i2c broadcasting address mapping */
			//设置广播地址
			max96712_write_reg(ambrg, addr, 0x0044, pinfo->i2c_ctrl.addr.sen_all);
			max96712_write_reg(ambrg, addr, 0x0045, ambrg->sensor_ctrl.dev_addr);

			if (pinfo->is_max9295d) {
   
   
				max96712_write_reg(ambrg
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

autho

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值