From c04d3dd7b3d026be03d2acbba1585d1824b5ea82 Mon Sep 17 00:00:00 2001 From: Hung-Te Lin Date: Wed, 5 Mar 2014 21:09:58 +0800 Subject: tegra124: Add tegra_dc_i2c_aux_read to allow reading EDID. To read EDID, we need to access I2C via DP AUX channel. BRANCH=none BUG=chrome-os-partner:25933 TEST=emerge-nyan coreboot chromeos-bootimage Original-Change-Id: I2666b5d46843485b79265a537f19bd8eab5e1a26 Original-Signed-off-by: Hung-Te Lin Original-Reviewed-on: https://chromium-review.googlesource.com/188858 Original-Reviewed-by: Gabe Black Original-Commit-Queue: Gabe Black (cherry picked from commit 8f8e98ff5038b57f89332aee75573095c3933dd2) Signed-off-by: Marc Jones Change-Id: I5b1b6ab2940c8265483059fd94a2c4db2a41144a Reviewed-on: http://review.coreboot.org/7735 Reviewed-by: Stefan Reinauer Tested-by: Stefan Reinauer --- src/soc/nvidia/tegra124/dp.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src/soc') diff --git a/src/soc/nvidia/tegra124/dp.c b/src/soc/nvidia/tegra124/dp.c index a9da269da9..e5c0632bb4 100644 --- a/src/soc/nvidia/tegra124/dp.c +++ b/src/soc/nvidia/tegra124/dp.c @@ -2,6 +2,7 @@ * drivers/video/tegra/dc/dp.c * * Copyright (c) 2011-2013, NVIDIA Corporation. + * Copyright 2014 Google Inc. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -322,6 +323,46 @@ static int tegra_dc_dp_dpcd_write(struct tegra_dc_dp_data *dp, u32 cmd, return ret; } +/* TODO(hungte) Change this to static when EDID parsing functions are ready. */ +int tegra_dc_i2c_aux_read(struct tegra_dc_dp_data *dp, u32 i2c_addr, + u8 addr, u8 *data, u32 *size, u32 *aux_stat); +int tegra_dc_i2c_aux_read(struct tegra_dc_dp_data *dp, u32 i2c_addr, + u8 addr, u8 *data, u32 *size, u32 *aux_stat) +{ + u32 finished = 0; + int ret = 0; + + do { + u32 cur_size = MIN(DP_AUX_MAX_BYTES, *size - finished); + + u32 len = 1; + ret = tegra_dc_dpaux_write_chunk( + dp, DPAUX_DP_AUXCTL_CMD_I2CWR, i2c_addr, + &addr, &len, aux_stat); + if (ret) { + printk(BIOS_ERR, "%s: error sending address to read.\n", + __func__); + break; + } + + ret = tegra_dc_dpaux_read_chunk( + dp, DPAUX_DP_AUXCTL_CMD_I2CRD, i2c_addr, + data, &cur_size, aux_stat); + if (ret) { + printk(BIOS_ERR, "%s: error reading data.\n", __func__); + break; + } + + /* cur_size should be the real size returned */ + addr += cur_size; + data += cur_size; + finished += cur_size; + } while (*size > finished); + + *size = finished; + return ret; +} + static void tegra_dc_dpaux_enable(struct tegra_dc_dp_data *dp) { /* clear interrupt */ -- cgit v1.2.3